c - argv[n] 是可写的吗?

标签 c language-lawyer

C11 5.1.2.2.1/2 说:

The parameters argc and argv and the strings pointed to by the argv 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;

我可以看到(至少)两个可能的论点:

  • 上面的引用故意提到了 argvargv[x][y] 但没有提到 argv[x],所以意图是它是不可修改的
  • argv 是指向非 const 对象的指针,因此在没有相反的特定措辞的情况下,我们应该假定它们是可修改的对象。

最佳答案

IMO,代码类似 argv[1] = "123";是 UB(使用原来的 argv )。


"The parameters argc and argv and the strings pointed to by the argv 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 的其他签名,缺少constchar *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/

相关文章:

c - 我的串联操作有什么问题?

c++ - 存档问题不是 C 中链接的体系结构 (x86_64)

在 C 中将 RGB 转换为灰度

c++ - 三元运算符中的条件 move 或复制赋值

c - C 中 printf() 中的大字段宽度

c++ - 函数定义中的四重 "const"

c - 为什么我们要在乘法中加一个点来运行程序?

c - 在 C 中修剪字符串(不使用库函数)

c++ - 应该在带花括号的 return 语句中调用什么构造函数?

c++ - 枚举位域和聚合初始化