这是以下产品的原型execv
:
int execv(const char *path, char *const argv[]);
我可以将const char
指针数组作为第二个参数传递吗?
如果USE_CAST
未设置此示例程序,则会发出警告:
#include <unistd.h>
int main(int argc, char *argv[])
{
if (argc > 0) {
const char *exe_name = "/bin/echo", *message = "You ran";
const char *exe_args[] = { exe_name, message, argv[0], NULL };
#ifdef USE_CAST
execv("/bin/echo", (char **) exe_args);
#else
execv("/bin/echo", exe_args);
#endif
}
return 0;
}
编译时,如果我不使用强制类型转换,gcc会说“从不兼容的指针类型传递'execv'的参数2”。
从POSIX文档中execv
(“原理”部分的一半),看起来第二个参数是一个char *const
仅用于向后兼容的数组:
包含有关
argv[]
和envp[]
为常数的声明,以使将来的语言绑定作者可以清楚地知道这些对象是完全恒定的。不幸的是,第四栏无法使用...
“第四列”是指const char* const[]
。
是(char **)
投安全在这里使用?我应该创建一个char *
数组并将其传递给它execv
吗?
我可以将const char指针数组作为第二个参数传递吗?
好吧,是的,您已经知道可以进行投射了。
从execv的POSIX文档(在“基本原理”部分中半步看),似乎第二个参数是char * const数组,仅用于向后兼容:
我不会用这些术语来表达,但是,是的,所选签名具有兼容性。您所参考的部分说明C不能完全令人满意地表达const
POSIXexecv()
提供参数所需的-ness程度。POSIX保证该函数不会更改指针argv
或它们指向的字符串。
在这种情况下,argv
尽管我会在代码中留下注释以解释为什么这样做是安全的,但我认为按照您的建议强制转换指针并不是没有道理的。
另一方面,您应该考虑简单地const
取消数组声明:
char *exe_name = "echo", *message = "You ran";
char *exe_args[] = { exe_name, message, argv[0], NULL };
或者,在您的简单示例中,即使这样做也可以:
char *exe_args[] = { "echo", message, argv[0], "You ran", NULL };
C字符串文字对应于typechar
而不是type的数组const char
,因此就C而言,这是完全合法的,即使实际上尝试修改这些字符串的内容可能会失败。
第三,现代C具有数组文字,因此您甚至可以执行以下操作:
execv("/bin/echo", (char *[]) { "echo", "You ran ", argv[0], NULL });
在最后一种情况下,您甚至没有强制转换(类似于一个强制转换的东西只是数组文字的语法的一部分)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句