我可以将const char *数组传递给execv吗? [英] Can I pass a const char* array to execv?

查看:115
本文介绍了我可以将const char *数组传递给execv吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是execv的原型:

int execv(const char *path, char *const argv[]);

我可以将const char指针数组作为第二个参数传递吗?

Can I pass an array of const char pointers as the second argument?

当未设置USE_CAST时,此示例程序会发出警告:

This example program gives a warning when USE_CAST is not set:

#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".

When compiling, gcc says, "passing argument 2 of 'execv' from incompatible pointer type" if I don't use the cast.

POSIX文档中找到execv(通过基本原理部分),看起来第二个参数是一个char *const数组,仅用于向后兼容:

From the POSIX documentation for execv (halfway through the Rationale section), it looks like the second argument is a char *const array only for backwards compatibility:

包含有关argv[]envp[]是常量的声明,以使将来的语言绑定作者可以清楚地知道这些对象是完全恒定的. ...很不幸,第四栏无法使用...

The statement about argv[] and envp[] being constants is included to make explicit to future writers of language bindings that these objects are completely constant. ... It is unfortunate that the fourth column cannot be used...

第四列"指的是const char* const[].

(char **)演员表在这里可以安全使用吗?我应该创建一个char *数组并将其传递给execv吗?

Is the (char **) cast safe to use here? Should I create a char * array and pass that to execv instead?

推荐答案

我可以将const char指针数组作为第二个参数传递吗?

Can I pass an array of const char pointers as the second argument?

是的,您已经知道可以进行投射.

Well yes, you already know that you can cast in order to do so.

从execv的POSIX文档(在基本原理"部分中半步看),看起来第二个参数是char * const数组,仅用于向后兼容:

From the POSIX documentation for execv (halfway through the Rationale section), it looks like the second argument is a char *const array only for backwards compatibility:

我不会用这些术语来表达,但是是的,所选签名具有兼容性.您所参考的部分说明C不能完全令人满意地表达POSIX要求execv()提供自变量的const -ness程度. POSIX保证该函数不会更改argv中的指针或它们指向的字符串.

I wouldn't put it in those terms, but yes, there is a compatibility aspect to the chosen signature. The section you reference explains that C does not have a wholly satisfactory way to express the degree of const-ness that POSIX requires execv() to provide for the arguments. POSIX guarantees that the function will not change either the pointers in argv or the strings to which they point.

在这种情况下,我认为按照您的建议强制转换argv指针并不是没有道理的,尽管我会在代码中留下注释,以说明这样做为什么是安全的.

With that being the case, I think it not unreasonable to cast the argv pointer as you propose to do, though I would leave a comment in my code explaining why doing so is safe.

另一方面,您应该考虑简单地将const保留在数组声明之外:

On the other hand, you should consider simply leaving the const off of your array declaration:

char *exe_name = "echo", *message = "You ran";
char *exe_args[] = { exe_name, message, argv[0], NULL };

或者,在您的简单示例中,即使这样做也可以:

Or, in your simple example, even this would do:

char *exe_args[] = { "echo", message, argv[0], "You ran", NULL };

C字符串文字对应于char类型的数组,而不是const char数组,因此就C而言,这是完全合法的,即使实际上尝试修改这些字符串的内容可能会失败.

C string literals correspond to arrays of type char, not const char, so this is perfectly legal as far as C is concerned, even though actually trying to modify the contents of those strings might fail.

另一方面,现代C具有数组文字,因此您甚至可以执行以下操作:

On the third hand, modern C has array literals, so you could even do this:

execv("/bin/echo", (char *[]) { "echo", "You ran ", argv[0], NULL });

在最后一种情况下,您甚至都没有强制转换(类似于一个强制转换的东西只是数组文字语法的一部分).

In that last case you don't even have a cast (the thing that resembles one is just part of the syntax for an array literal).

这篇关于我可以将const char *数组传递给execv吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆