编译器是否可以在 c++ 中存储分配后知道变量的值?如果给出以下代码,c编译器是什么情况
const int bufsize = 100;
char buf[bufsize];
文字解释如下:“在 C 语言中,你会得到一个错误,尽管这看起来很合理。因为 bufsize 在某处占用存储空间,所以 C 编译器无法在编译时知道该值。” 为什么这么说?
在 C99 中,如果代码在函数内部,这很好;该变量被视为运行时值,但数组可以具有可变长度。如果它有静态存储是不允许的。
在 C++ 中,这很好;整数const
变量可用作编译时值。
在旧版本的 C 中,这是不允许的。该变量是运行时值,并且不存在可变长度数组。
为什么这么说?
因为这就是语言设计者决定语言应该表现的方式。
C89 不允许这样做,因为 aconst int
不被视为常量表达式,并且数组的大小必须指定为常量表达式。
在 C99(和更高版本)中,可变长度数组消除了将数组大小作为常量表达式给出的要求,因此这是允许的(允许 VLA 的地方,基本上是:使用自动存储类 - 而不是作为static
或全局)。
C++ 要求将数组的大小指定为常量表达式(如 C89),但允许将 aconst int
作为常量表达式1,因此这是允许的。
1正如@JamesKanze 指出的那样,只是aconst int
并不能保证变量的值将被视为常量表达式。只const int
允许具有可见初始化程序且本身是常量表达式的 a ——但这些限制在此处得到满足。
在 C中,const
声明不会产生常量表达式,而在 C++ 中会产生。
所以,
const int bufsize = 100;
char buf[bufsize];
在 C++ 中有效,但在 C 中无效。
但是,请注意,由于 c99 标准允许变长数组(VLA),因此 VLA 不是 C++ 标准的一部分,但大多数编译器通过编译器扩展支持它们。
“在 C 语言中,你会得到一个错误,尽管这看起来很合理。因为 bufsize 在某处占用存储空间,C 编译器无法在编译时知道该值。” 为什么这么说?
因为在 C 中,bufsize
不是 const 表达式;它是一个只读值:
const int bufsize = 100; //read-only in C
//constant expression in C++
const 表达式和 readonly 之间的区别在于,前者意味着编译器知道该值(在编译时本身),而后者意味着该值是只读的,编译器不知道该值。
请注意,在 C++ 中,buffsize
and100
是 const 表达式,而在 C 中,只有100
const 表达式。声明数组的大小需要为 const 表达式;因此,仅在 C++ 中允许以下内容(在允许 VLA 的 C99 中,这是另一个故事):
char buf[bufsize]; //ok in C++ (and C99)
//error in C89, C90
相比之下,显然最明显的语言泛化(即允许在数组边界中使用通用表达式而不是常量)使语言的类型结构复杂化,导致数据类型计算困难,并导致发现数组大小的不均匀性。
(摘自 Journal of C Language Translation,第 2 卷第 2 期,作者 Dennis Ritchie)
在这篇论文中,他呼吁标准机构避免使用 VLA。
然而,在后来的 C (C99) 版本中,对此进行了审查,他们允许在非全局范围内使用可变长度数组。
在 C++ 中,这是有效的,因为 const 声明的变量被视为常量表达式。