c++中存储分配后的变量值

value of the variable after storage allocation in c++

本文关键字:变量值 分配 存储 c++      更新时间:2023-10-16

编译器有可能知道c++中存储分配后变量的值吗?如果下面的代码被赋予,那么c编译器的情况是什么

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

文本解释如下:"在C中,你会得到一个错误,尽管这似乎是一件合理的事情因为bufsize占用了某个地方的存储空间,所以C编译器在编译时无法知道该值。"为什么这么说?

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

在C++中,这很好;可以使用CCD_ 1整数变量作为编译时值。

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

为什么这么说?

因为这就是语言设计者决定语言行为的方式。

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

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

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


1正如@JamesKanze所指出的,仅仅const int并不能保证变量的值被视为常数表达式。只允许具有可见初始值设定项的const int本身就是常量表达式,但这里满足了这些限制。

在Cconst声明中不会产生常量表达式,而它们在C++中会产生
所以,

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

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

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

"在C中,你会得到一个错误,尽管这样做似乎是合理的。因为bufsize占用了某个地方的存储空间,C编译器在编译时无法知道值。"为什么这么说?

因为在C中,bufsize不是常量表达式;它是只读值:

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

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

注意,在C++中,buffsizeconst0是常量表达式,而在C中,只有100是常量表达式。声明的数组的大小必须是const表达式;因此,以下内容仅在C++中允许(在C99中允许VLA,这是另一回事):

char buf[bufsize]; //ok in C++ (and C99)
                   //error in C89, C90

这个问题的历史可以追溯到80年代,已故的Dennis Ritchie曾说过

相比之下,最明显的语言泛化(即,允许使用通用表达式而不是数组中的常量边界)使语言的类型结构复杂化,导致数据类型的计算困难,并导致不均匀性在发现阵列的大小方面
(摘自《C语言翻译杂志》第2卷第2期,Dennis Ritchie著)

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

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

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