C11 5.1.2.2.1/2 说:
The parameters
argc
andargv
and the strings pointed to by theargv
array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
我对此的解释是:
int main(int argc, char **argv)
{
if ( argv[0][0] )
argv[0][0] = 'x'; // OK
char *q;
argv = &q; // OK
}
然而它并没有说明:
int main(int argc, char **argv)
{
char buf[20];
argv[0] = buf;
}
是否允许argv[0] = buf;
?
我可以看到(至少)两个可能的论点:
- 上面的引用故意提到了
argv
和argv[x][y]
但没有提到argv[x]
,所以意图是它是不可修改的 argv
是指向非const
对象的指针,因此在没有相反的特定措辞的情况下,我们应该假定它们是可修改的对象。
最佳答案
IMO,代码类似 argv[1] = "123";
是 UB(使用原来的 argv
)。
"The parameters
argc
andargv
and the strings pointed to by theargv
array shall be modifiable by the program, and retain their last-stored values between program startup and program termination." C11dr & C17dr1 §5.1.2.2.1 2
回想一下 const
在 C 创建多年后进入 C。
很像char *s = "abc";
在应该为 const char *s = "abc";
时有效.需要 const
不需要,否则过多的现有代码会随着 const
的引入而被破坏。 .
同样,即使argv
今天应该考虑char * const argv[]
或带有 const
的其他签名,缺少const
在char *argv[]
没有完全指定 const
-ness 需求 argv
, argv[]
, 或 argv[][]
. const
-ness 需求需要由规范驱动。
根据我的阅读,由于规范在这个问题上没有提及,但深入探讨了 main()
的其他任务。的 argv =
和 argv[i][j] =
, 就是UB。
Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior" §4 2
[编辑]:
main()
在 C 中是一个非常特殊的函数。在其他函数中允许的功能在 main()
中可能允许也可能不允许。 . C 规范详细说明了其参数的属性,这些参数给出了签名 int argc, char *argv[]
那不应该需要。 main()
,与 C 中的其他函数不同,可以具有备用签名 int main(void)
和可能的其他人。 main()
不可重入。由于 C 规范竭尽全力详细说明可以修改的内容:argc
, argv
, argv[][]
, 质疑 argv[]
是否合理是合理的是可修改的,因为它在声明代码可以的规范中被遗漏了。
鉴于 main()
的特殊性以及省略指定 argv[]
作为可修改的,保守的程序员会将这种灰色视为 UB,等待 future 的 C 规范澄清。
如果argv[i]
在给定平台上是可修改的,当然是 i
的范围不应超过 argc-1
.
因为“argv[argc]
应该是一个空指针”,分配argv[argc]
到NULL
以外的东西似乎是违规行为。
虽然字符串是可修改的,但代码不应超过原始字符串的长度。
char *newstr = "abc";
if (strlen(newstr) <= strlen(argv[1]))
strcpy(argv[1], newstr);
1 C17/18 没有变化。由于该版本旨在澄清许多事情,因此它再次强调该规范是足够的并且没有遗漏“argv
数组元素应是可修改的”。
关于c - argv[n] 是可写的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25737434/