我经常在C++中使用execv()函数,但是如果一些参数是C++字符串,我就不能这样做了,这让我很恼火:
const char *args[4];
args[0] = "/usr/bin/whatever";
args[1] = filename.c_str();
args[2] = someparameter.c_str();
args[3] = 0;
execv(args[0], args);这不能编译,因为execv()使用与const char *不兼容的char *const argv[],所以我不得不使用strdup()将我的std::string复制到字符数组,这是一件痛苦的事情。
有人知道这是什么原因吗?
发布于 2008-10-10 05:20:20
Open Group Base规范解释了这是为什么:为了与现有的C代码兼容。不过,指针和字符串内容本身都不打算更改。因此,在这种情况下,您可以使用const_cast-ing c_str()的结果。
Quote:
中包含了关于
argv[]和envp[]是常量的语句,以向未来的语言绑定编写者明确说明这些对象是完全常量的。由于ISO C标准的限制,无法在标准C中说明这一思想。为exec函数的argv[]和envp[]参数指定两个级别的const限定似乎是自然而然的选择,因为这些函数既不修改指针数组,也不修改函数所指向的字符,但这将不允许现有的正确代码。相反,只有指针数组被标记为常量。
后面的表格和文本甚至更有洞察力。然而,Stack Overflow不允许插入表,所以上面的引号应该是足够的上下文,让您在链接的文档中搜索正确的位置。
发布于 2008-10-10 05:16:08
C++是一种C++ - execv在C++出现之前就已经接受了char *参数。
您可以使用const_cast而不是复制,因为execv实际上并不修改它的参数。您可以考虑编写一个包装器来省去输入。
实际上,代码中更大的问题是声明了一个字符数组,而不是字符串数组。
尝试: const char* args4;
发布于 2015-04-08 05:46:09
这只是一种C/ C++风格的常量不能很好工作的情况。实际上,内核不会修改传递给exec()的参数。它只是在创建新进程时复制它们。但是类型系统的表现力还不足以很好地处理这个问题。
这个页面上的很多人都建议让exec使用" char **“或"const char* const[]”。但这两种方法实际上都不适用于您的原始示例。"char**“意味着所有东西都是可变的(对于字符串常量”/usr/bin/bin“肯定不是这样的)。"const char *const[]“意味着没有任何东西是可变的。但是,您不能将任何值赋给数组的元素,因为数组本身是const。
你能做的最好的事情就是拥有一个编译时的C常量,如下所示:
const char * const args[] = {
"/usr/bin/whatever",
filename.c_str(),
someparameter.c_str(),
0};这实际上将与建议的类型签名"const char *const[]“一起工作。但是,如果您需要可变数量的参数怎么办?那么你不能有一个编译时常量,但是你需要一个可变的数组。所以你又开始胡编乱造了。这就是为什么exec的类型签名以"const char **“作为参数的真正原因。
顺便说一下,这些问题在C++中也是一样的。不能将std::vector < std::string >传递给需要std::vector < const std::string >的函数。您必须对整个std::vector进行类型转换或复制。
https://stackoverflow.com/questions/190184
复制相似问题