Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
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 - Fatal编程技术网

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
-ing
c\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);
}

)/ 这一页上的许多人建议让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传递给需要std::vector的函数。您必须键入或复制整个std::vector。

哦,我的意思是键入const char*,要么是键入错误,要么是堆栈溢出选中了星号。我会编辑这个问题。ExcV不会接受const char *ARG[]——至少不接受G++,但是谢谢你的回答,我确实考虑过铸造到非const,但是我不知道是否安全。C编译器允许你把conchar *传递给ExRV,但是它会发出警告。对于C++编译器,需要使用conconsCasic。“const是C++的东西”——const是C语言,在C++中被标准化之前在C中被标准化。“Excv从C++之前就已经开始了char *”——但是在C存在之后(但是在C被标准化之前)。const不是“C++的东西”。它存在于C++之前很久,我会接受这个答案,尽管乔纳森的答案是相似的。在我看来,这个词用得更好。谢谢!我只是在引用的文章中补充了一点,说明人们应该继续阅读;它更好地解释了基本原理,以及如果不是为了兼容性,char const*const[]会更可取的原因。@user877329该声明存在于
中,只有您的操作系统提供商才能更改。当然,您不能期望用户代码能够覆盖其内容。@ChrisJester-Young。我和《标准报》谈过了commite@user877329-在
#ifdef uu cplusplus uu
中应该包含一组内联重载,这些重载在适当的强制转换后转发到主系统函数。该表提供了一个令人信服的案例,这是确保函数采用其应采用的所有不同参数类型的唯一方法。我认为,如果您确定所执行的程序不会更改其参数,则可以安全地使用const_cast。我已经为每个系统调用编写C++包装器,所以系统调用抛出异常,而不是检查返回值。作为其中的一部分,我只是创建了一组重载来为我执行所有的
常量转换
,这样我就不必让它们散布在整个代码中。由于两个参数都是常量/非常量,因此需要定义execve才能使其工作。当然,其中之一是系统定义。其他函数只是内联函数,它们转发到给定适当类型转换的函数