0

编译器是否可以在 c++ 中存储分配后知道变量的值?如果给出以下代码,c编译器是什么情况

const int bufsize = 100;
char buf[bufsize];

文字解释如下:“在 C 语言中,你会得到一个错误,尽管这看起来很合理。因为 bufsize 在某处占用存储空间,所以 C 编译器无法在编译时知道该值。” 为什么这么说?

4

5 回答 5

3

在 C99 中,如果代码在函数内部,这很好;该变量被视为运行时值,但数组可以具有可变长度。如果它有静态存储是不允许的。

在 C++ 中,这很好;整数const变量可用作编译时值。

在旧版本的 C 中,这是不允许的。该变量是运行时值,并且不存在可变长度数组。

为什么这么说?

因为这就是语言设计者决定语言应该表现的方式。

于 2012-08-21T15:02:37.183 回答
3

C89 不允许这样做,因为 aconst int不被视为常量表达式,并且数组的大小必须指定为常量表达式。

在 C99(和更高版本)中,可变长度数组消除了将数组大小作为常量表达式给出的要求,因此这是允许的(允许 VLA 的地方,基本上是:使用自动存储类 - 而不是作为static或全局)。

C++ 要求将数组的大小指定为常量表达式(如 C89),但允许将 aconst int作为常量表达式1,因此这是允许的。


1正如@JamesKanze 指出的那样,只是aconst int并不能保证变量的值将被视为常量表达式。只const int允许具有可见初始化程序且本身是常量表达式的 a ——但这些限制在此处得到满足。

于 2012-08-21T15:05:09.357 回答
2

在 C中,const声明不会产生常量表达式,而在 C++ 中会产生。
所以,

const int bufsize = 100;
char buf[bufsize];

在 C++ 中有效,但在 C 中无效。

但是,请注意,由于 c99 标准允许变长数组(VLA),因此 VLA 不是 C++ 标准的一部分,但大多数编译器通过编译器扩展支持它们。

于 2012-08-21T15:01:46.480 回答
1

“在 C 语言中,你会得到一个错误,尽管这看起来很合理。因为 bufsize 在某处占用存储空间,C 编译器无法在编译时知道该值。” 为什么这么说?

因为在 C 中,bufsize不是 const 表达式;它是一个只读值:

const int bufsize = 100; //read-only in C
                         //constant expression in C++

const 表达式和 readonly 之间的区别在于,前者意味着编译器知道该值(在编译时本身),而后者意味着该值是只读的,编译器不知道该值。

请注意,在 C++ 中,buffsizeand100是 const 表达式,而在 C 中,只有100const 表达式。声明数组的大小需要为 const 表达式;因此,仅在 C++ 中允许以下内容(在允许 VLA 的 C99 中,这是另一个故事):

char buf[bufsize]; //ok in C++ (and C99)
                   //error in C89, C90
于 2012-08-21T15:01:55.710 回答
0

这个问题的历史可以追溯到 80 年代,已故丹尼斯·里奇 (Dennis Ritchie) 曾说过

相比之下,显然最明显的语言泛化(即允许在数组边界中使用通用表达式而不是常量)使语言的类型结构复杂化,导致数据类型计算困难,并导致发现数​​组大小的不均匀性。
(摘自 Journal of C Language Translation,第 2 卷第 2 期,作者 Dennis Ritchie)

在这篇论文中,他呼吁标准机构避免使用 VLA。

然而,在后来的 C (C99) 版本中,对此进行了审查,他们允许在非全局范围内使用可变长度数组。

在 C++ 中,这是有效的,因为 const 声明的变量被视为常量表达式。

于 2012-08-21T15:22:29.543 回答