C 数组绑定在';]之前不是整数常量';当它实际上是常量时的标记

C 数组绑定在';]之前不是整数常量';当它实际上是常量时的标记,c,C,我正在尝试创建一个数组,该数组在编译时具有已知的已定义大小 const uint8_t a[2] = {0, 127}; // Fine const uint8_t aRange = a[1] - a[0]; // Fine double sums[aRange]; //Fails 但gcc却未能做到这一点 错误:数组绑定不是“]”标记之前的整数常量 作为一种解决方法,我打算使用宏变量。但我想知道这背后是否有任何逻辑。有一个答案,这是最相关的。然而,根据答案,它应该是有效的。aRange是一个

我正在尝试创建一个数组,该数组在编译时具有已知的已定义大小

const uint8_t a[2] = {0, 127}; // Fine
const uint8_t aRange = a[1] - a[0]; // Fine
double sums[aRange]; //Fails
但gcc却未能做到这一点

错误:数组绑定不是“]”标记之前的整数常量


作为一种解决方法,我打算使用宏变量。但我想知道这背后是否有任何逻辑。有一个答案,这是最相关的。然而,根据答案,它应该是有效的。

aRange
是一个常量整数,但不是一个整数常量。英语不是一种有趣的语言吗

  • C11
  • C11
    • 整数常量表达式117)应为整数类型,且只能包含整数常量操作数、枚举常量、字符常量、
      sizeof
      表达式(其结果为整数常量)、
      \u Alignof
      表达式以及作为强制转换直接操作数的浮点常量。整型常量表达式中的强制转换运算符只能将算术类型转换为整型,除非作为操作数的一部分转换为
      sizeof
      \u Alignof
      运算符
    • 117)在许多上下文中需要整数常量表达式,例如结构的位字段成员的大小、枚举常量的值和非可变长度数组的大小。6.10.1中讨论了适用于条件包含预处理指令中使用的整数常量表达式的进一步约束
  • C11-标准中较难理解的部分之一。(^2是一个约束;^4和^5指定数组声明器的语义。)
    • ^2如果标识符被声明为具有可变修改类型,则其应为普通标识符(如6.2.3中所定义),无链接,且具有块范围或功能原型范围。如果标识符被声明为具有静态或线程存储持续时间的对象,则它不应具有可变长度数组类型
    • 如果大小不存在,则数组类型为不完整类型。如果大小为
      *
      而不是表达式,则数组类型为大小未指定的可变长度数组类型,只能在具有函数原型作用域的声明或类型名称中使用;143)尽管如此,此类阵列仍然是完整的类型。如果大小是整数常量表达式,且元素类型具有已知常量大小,则数组类型不是可变长度数组类型;否则,数组类型为可变长度数组类型。(可变长度数组是一种实现不需要支持的条件功能;请参见6.10.8.3。)
    • 143)因此,
      *
      只能用于非定义的函数声明(见6.7.6.3)
    • ^5如果大小是一个不是整数常量表达式的表达式:如果它出现在函数原型范围的声明中,则将其视为被替换为
      *
      ;否则,每次评估时,其值应大于零。可变长度数组类型的每个实例的大小在其生存期内不会更改。如果大小表达式是
      sizeof
      运算符的操作数的一部分,并且更改大小表达式的值不会影响运算符的结果,则未指定是否计算大小表达式
在文件(全局)范围内,数组的维度必须有一个整数常量表达式。在C99或更高版本的局部变量中,您所写的内容对于VLA(可变长度数组)来说是可以的

您可以通过以下方式解决此问题:

enum { A_MIN = 0, A_MAX = 127 };
const uint8_t a[2] = { A_MIN, A_MAX };
const uint8_t aRange = a[1] - a[0];
double sums[A_MAX - A_MIN];

在C语言中,不能编写
constuint8\u t aRange=a[1]-a[0]在文件(全局)范围内,因此您的代码应该是正常的,除非您使用的是不识别C99或更高版本的过时C编译器(或者它定义了
\u STDC\u NO\u VLA\u
)。

乔纳森的答案被接受。不过,作为一种解决方法,我使用了宏

#define A_MIN 0
#define A_MAX 127
const uint8_t a[2] = {A_MIN, A_MAX};
const uint8_t aRange = A_MAX - A_MIN;
double sums[aRange];

在全局(非函数)范围内,所有数组大小都必须是编译时常量。即使将
aRange
定义为
const
,它也不是编译时常量。c中的<代码> const 限定符只表示变量值不能被修改。升级到C++,我认为编译器足够聪明,可以生成常数整数,整数常数,因为所有必要的东西在编译时都是已知的。C语言不允许这样做。C++有不同的规则;你在那里可能会没事的。请看: