首页 > 解决方案 > argv = NULL 是什么意思?

问题描述

我正在尝试使参数信息不可修改。

#include <stdio.h>
#include <stdlib.h>

int main(const int argc, const char* const argv[]) {
  //argc = 1;         // error: assignment of read-only parameter 'argc'
  //argv[0] = "argv"; // error: assignment of read-only location '*argv'
  //argv[0][0] = 'a'; // error: assignment of read-only location '**argv'
  return EXIT_SUCCESS;
}

现在当我这样做时,

argv = NULL; // no compile-time error

编译器保持沉默。

该声明实际上做了什么?我怎样才能禁止我的代码这样做?

标签: c

解决方案


好吧,首先,不要这样做

我参考了现有的答案来了解const你将如何做到这一点,他们解释了可以应用的不同级别以及如何用直接指针语法以及“伪装成数组”-syntax来编写它。这绝对是件好事。

但它来了:main很特别。根据 C 标准,它没有原型,但定义只能采用两种形式之一。这是原始文本,从N1570到 C11 的最新草案:

§ 5.1.2.2.1

程序启动时调用的函数名为main. 实现没有声明这个函数的原型。它应该被定义为返回类型int和不带参数:
int main(void) { /* ... */ }
或有两个参数(这里称为argcargv,尽管可以使用任何名称,因为它们对于声明它们的函数是局部的):
int main(int argc, char *argv[]) { /* ... */ }
或等效的;10)或以其他一些实现定义的方式。

脚注 10 甚至解释了等效的含义:

因此,int可以替换为定义为 的 typedef 名称int,或者argv可以写为 的类型char ** argv,依此类推。

但至于添加一些consts,例如在§ 6.7.6.1 p2中查看:

对于要兼容的两种指针类型,两者都应具有相同的限定,并且都应是指向兼容类型的指针。

(强调我的)。const是一个类型限定符。所以const char **不兼容。_ char **您定义的 amain不再符合 C 标准。因此,不要这样做。在程序内部使用const正确性,但不要尝试更改程序启动界面。


旁注:正是 const在这里询问的那个可能没问题,因为它适用于指针本身,它只是函数的局部变量(因为参数在 C 函数调用中总是按值)。所以它不会改变函数的接口。这就是为什么在实践中,没有人会费心添加这样const的 s。函数是否修改其局部变量对于调用代码并不重要。


推荐阅读