execv()与常量 我经常在C++中使用 ExcVIEW()/Cuff>函数,但是如果一些参数是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()与常量 我经常在C++中使用 ExcVIEW()/Cuff>函数,但是如果一些参数是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);,c++,unix,C++,Unix,这不会编译,因为execv()使用char*const argv[]与const char*不兼容,所以我必须使用strdup()将我的std::string复制到字符数组中,这是一个难题 有人知道这个原因吗?< /P> < P> const是C++的一个东西。Excv在C++存在之前就已经采取了char *参数。 您可以使用const_cast而不是复制,因为execv实际上并不修改其参数。你可以考虑写一个包装来保存你自己的打字。 实际上,代码的一个更大的问题是声明了字符数组而不是字符串数组
execv()
使用char*const argv[]
与const char*
不兼容,所以我必须使用strdup()
将我的std::string
复制到字符数组中,这是一个难题
有人知道这个原因吗?< /P> < P> const是C++的一个东西。Excv在C++存在之前就已经采取了char *参数。 您可以使用const_cast而不是复制,因为execv实际上并不修改其参数。你可以考虑写一个包装来保存你自己的打字。
实际上,代码的一个更大的问题是声明了字符数组而不是字符串数组 尝试:常量字符*args[4] 开放组基本规范解释了原因:为了与现有C代码兼容。不过,指针和字符串内容本身都不打算更改。因此,在这种情况下,您可以通过
const\u cast
-ingc\u str()
的结果而不受影响
包含关于argv[]
和envp[]
是常量的语句是为了向语言绑定的未来编写者明确说明这些对象是完全常量。由于ISO C标准的限制,无法在标准C中说明这一想法。为exec函数的argv[]
和envp[]
参数指定两个级别的const
-限定似乎是自然选择,假设这些函数既不修改指针数组,也不修改函数指向的字符,但这将不允许现有的正确代码。相反,只有指针数组被记为常量
之后的表格和文本更具洞察力。但是,堆栈溢出不允许插入表,因此上面的引号应该足以让您在链接文档中搜索正确的位置。我通常使用以下方法来解决此问题:
#define execve xexecve
#include <...>
#include <...>
#include <...>
#undef execve
// in case of c++
extern "C" {
int execve(const char * filename, char ** argvs, char * const * envp);
}
#定义execve xecve
#包括
#包括
#包括
#未定义execve
//在C++中
外部“C”{
int execve(常量字符*文件名,字符**argvs,字符*常量*envp);
}
)/这只是C/C++风格不太好的一个例子。实际上,内核不会修改传递给exec()的参数。它只是在创建新流程时复制它们。但是类型系统没有足够的表达能力来很好地处理这个问题 这一页上的许多人建议让exec使用“char**”或“const char*const[]”。但这两种方法都不适用于您最初的示例。“char**”表示一切都是可变的(字符串常量“/usr/bin/whatever”肯定不是真的)。“const char*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
中,只有您的操作系统提供商才能更改。当然,您不能期望用户代码能够覆盖其内容。@ChrisJester-Young。我和《标准报》谈过了commite@user877329-在#ifdef uu cplusplus uu
中应该包含一组内联重载,这些重载在适当的强制转换后转发到主系统函数。该表提供了一个令人信服的案例,这是确保函数采用其应采用的所有不同参数类型的唯一方法。我认为,如果您确定所执行的程序不会更改其参数,则可以安全地使用const_cast。我已经为每个系统调用编写C++包装器,所以系统调用抛出异常,而不是检查返回值。作为其中的一部分,我只是创建了一组重载来为我执行所有的常量转换
,这样我就不必让它们散布在整个代码中。由于两个参数都是常量/非常量,因此需要定义execve才能使其工作。当然,其中之一是系统定义。其他函数只是内联函数,它们转发到给定适当类型转换的函数