为什么没有argv和envp参数来执行指向const的指针?

时间:2014-10-14 19:22:26

标签: process c posix

拿走,例如execve(2),根据posix有这个原型[1]:

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

对我来说,好像好像是

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

会有明显的改善。

那么,有谁知道为什么会这样?什么可以解释需要 可能操纵给定的argv / envp字符串?

[1] http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html

3 个答案:

答案 0 :(得分:2)

argv的{​​{1}}和envp参数不是指向execve()的指针,以保持与在const之前编写的有效C代码的向后兼容性。已添加到C。

C首先出现in 1972。后来,const被添加到C in 1987.

为了保持与const之前的代码的兼容性,const的{​​{1}}更新声明必须能够接受非const的输入。 C不允许从execve()const进行分配。可以通过尝试(但失败)编译以下程序来验证这一点:

char *[]

因此,const char *[]是最严格的类型,它与之前的void foo ( const char * argv[] ) { return; } void main ( int argc, char * argv[] ) { foo ( argv ); } 代码向后兼容。

该问题提供了指向char *const[]的POSIX文档的链接。链接的POSIX文档确实对此进行了如下解释:

关于constexecve()是常量的语句包括到 向未来的语言绑定作者明确 对象是完全恒定的。由于ISO C的限制 标准,就不可能在标准C中陈述该想法。

实际上,确切地说:不可能以与{argv[]以前的代码向后兼容的方式声明该想法。

...为envp[]const指定两个级别的 const-资格 exec 函数的argv[]参数似乎很自然 选择,因为这些函数不会修改 指针或函数指向的字符,但这 会禁止现有正确的代码。相反,只有 指针被标记为常量。分配兼容性表 源自ISO C标准的 dst = src 总结了 兼容性:

envp[]

由于所有现有代码...

表示将 dst: char *[] const char *[] char *const[] const char *const[] src: char *[] VALID - VALID - const char *[] - VALID - VALID char * const [] - - VALID - const char *const[] - - - VALID 添加到C之前存在的所有代码。

...具有与第一行匹配的源类型, 提供最有效组合的列是第三列。的 仅有的其他可能性是第四列,但使用它会 需要对constargv参数进行强制转换。不幸的是 不能使用第四列,因为声明是非专家 自然会使用第二行中的那个。

来源:2018 edition2004 edition

答案 1 :(得分:0)

这基本上是由于C标准中的漏洞阻止了从T **const T * const *的隐式转换。这样的转换是安全的(从T**const T **的转换是有问题的),但是标准尚未进行更新以允许它。

POSIX标准中的

mpb报价

包含有关argv []和envp []为常量的声明,以便将来向语言绑定的作者明确说明这些对象是完全恒定的。由于ISO C标准的局限性,因此无法在标准C中陈述该想法。

这意味着当/如果C标准已更新,则POSIX标准将被更改。

答案 2 :(得分:-1)

某些程序操纵argv字符串,以便ps输出显示一些状态信息。例如:

root      6550 10809  0 13:10 ?        00:00:00 pure-ftpd (IDLE)
root     32216     1  0 Apr05 ?        00:00:00 vtund[s]: waiting for connections on port 5000
1023     30448  9847  0 09:01 ?        00:00:01 imap [username 192.168.1.135]

因此argv值不是常量,不应该这样声明。