【问题标题】:In C, why can't a const variable be used as an array size initializer? [duplicate]在 C 中,为什么不能将 const 变量用作数组大小初始值设定项? [复制]
【发布时间】:2017-10-31 06:12:06
【问题描述】:

在以下代码中,const int 不能用作数组大小:

const int sz = 0;
typedef struct
{
   char s[sz];
} st;

int main()
{
   st obj;
   strcpy(obj.s, "hello world");
   printf("%s", obj.s);
   return 0;
}

【问题讨论】:

  • 因为数组的大小必须是一个常数,而一个const变量是一个const变量,而不是一个常数,这意味着它不能被改变
  • 只是语言的另一个缺陷。
  • ...在 C++ 中已修复。
  • @Mgetz const 整数变量如果有 constexpr 初始化器,就会隐式变为 constexpr
  • 你很幸运代码没有构建,因为如果它构建了,你会有未定义的行为写入一个零大小的数组。

标签: c


【解决方案1】:

在 C 中,const 限定变量不是常量表达式1。常量表达式是可以在编译时求值的东西 - 像 103.14159 这样的数字文字,像 "Hello" 这样的字符串文字,sizeof 表达式,或由相同的表达式组成,如 @987654326 @。

对于文件范围内的数组声明(在任何函数体之外)或作为structunion 类型的成员,数组维度必须是一个常量表达式。

对于auto 数组(在函数体中声明的不是static 的数组),您可以使用其值在运行时才知道的变量或表达式,但只能在 C99 或更高版本中。


  1. C++ 在这方面有所不同 - 在该语言中,const 限定变量确实 算作常量表达式。

【讨论】:

  • 不能断言const-qualified 变量不是常量表达式。尽管 C 标准不要求 常量表达式 包含 const 限定变量,但 C 2018 6.6 10 表示“实现可以接受其他形式的常量表达式。” (同样的文本在 C 1999 中。)
  • C 与 C++ 的不同之处还在于,10 不称为数字文字,而是称为整数常量。另外:C 的 literalsstringcompound 可以获取它们的地址,这与整数常量不同。
【解决方案2】:

这是因为在 C 中const 实际上意味着只读。引用C FAQ 1.18 and 1.19:

const 限定符的真正意思是“只读”;如此限定的对象是不能(通常)分配给的运行时对象。因此, const 限定对象的值不是完全意义上的常量表达式,不能用于数组维度、案例标签等。 (在这方面,C 与 C++ 不同。)当您需要真正的编译时常量时,请使用预处理器 #define(或者可能是枚举)。

参考:ISO Sec. 6.4 H&S 秒。 7.11.2,7.11.3 第 226-7 页

有两种处理方式:

  1. 使用#define 而不是const
  2. 使用enum { sz = 12 };

【讨论】:

    【解决方案3】:

    以一种非常简单的方式,因为编译器必须在编译时知道数组的维度,并且由于您可以在运行时初始化 const variable,所以您无法做到这一点。所以静态声明数组的大小必须是一个常量表达式,而const variable不是。对于常量表达式,您应该使用宏 (#define) 或 enum。如果您使用c99 的最低标准,这明确适用于您的情况(在文件范围内)。

    【讨论】:

      猜你喜欢
      • 2019-12-24
      • 2014-11-23
      • 2021-02-20
      • 2013-10-21
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      相关资源
      最近更新 更多