我可以将const char *数组传递给execv吗?

时间:2016-04-28 21:00:57

标签: c exec posix const const-correctness

这是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}}吗?

2 个答案:

答案 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还是不。