这是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;
}
指针数组作为第二个参数吗?
此示例程序在未设置execv
时发出警告:
char *const
编译时,gcc说,“如果我不使用强制转换,则从不兼容的指针类型传递'execv'的参数2”。
从argv[]
envp[]
(基本原理部分的中间),看起来第二个参数是const char* const[]
数组,仅用于向后兼容:
包含有关
(char **)
和char *
为常量的语句,以便明确将来语言绑定的编写者使这些对象完全不变。 ......遗憾的是第四栏无法使用......
其中“第四列”是指execv
。
X pred1 pred2 pred3
(46020, 369) (46020,) (46020,) (46020,)
施法者在这里可以安全使用吗?我应该创建一个array_pack = np.column_stack((X, pred1, pred2, pred3))
数组并将其传递给{{1}}吗?
答案 0 :(得分:3)
我可以传递一个const char指针数组作为第二个参数吗?
是的,你已经知道你可以为了这样做而施展。
从execv的POSIX文档(在Rationale部分的中间),看起来第二个参数是char * const数组,仅用于向后兼容:
我不会用这些术语来表达,但是,是的,所选签名存在兼容性方面。您引用的部分解释了C没有完全令人满意的方式来表达POSIX要求const
提供参数的execv()
的程度。 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字符串文字对应于char
类型的数组,而不是const char
,因此就C而言,这是完全合法的,即使实际尝试修改这些字符串的内容可能会失败。
第三方面,现代C有数组文字,所以你甚至可以这样做:
execv("/bin/echo", (char *[]) { "echo", "You ran ", argv[0], NULL });
在最后一种情况下,你甚至没有一个强制转换(类似于一个的东西只是数组文字语法的一部分)。
答案 1 :(得分:1)
如果您要丢弃const
,那么您不应该使用const
开头。大多数(我敢说所有)编译器都会接受以下代码
char *exe_name = "/bin/echo";
char *message = "You ran";
char *exe_args[] = { exe_name, message, argv[0], NULL };
execv( exe_args[0], exe_args );
如果这对你来说不够迂腐,那么另一个选择就是
char exe_name[] = "/bin/echo";
char message[] = "You ran";
char *exe_args[] = { exe_name, message, argv[0], NULL };
execv( exe_args[0], exe_args );
请注意execv
将创建字符串的副本(为可执行文件创建argv
数组),因此字符串实际上是const
还是不。