const
变量必须初始化意味着 uninitialized const variable
是不可能的,并且这是一个编译器错误。但为什么在C语言中也不一样呢?
考虑以下可以编译良好 C 的程序:
#include <stdio.h>
int main()
{
const int a;
}
允许
uninitialized const
的理由是什么?如果 C 也遵循与 C++ 相同的规则,那不是很好吗?是否出于性能考虑,每次调用函数时都需要初始化局部 const 变量并且初始化需要时间?
这种差异可能源于,除其他外,C 语言中的初始化方法一般而言更加宽松,而不仅仅是针对
const
对象。例如,这段代码在C++中是非法的
goto over;
int a = 5;
over:;
因为它绕过初始化跳转到
a
的范围。同时,在 C 中,这段代码是完全合法的,变量 a
在 over:
处具有不确定的值。
同样的逻辑也适用于您的
const int a
声明。 C 语言只是认为未初始化的对象没什么大不了的,即使在以后不再可能将其设置为确定值的情况下也是如此。
C++ 中更严格的初始化要求的主要原因是在语言中引入了重要的初始化(构造函数),即无法有意义地绕过的初始化。 C++ 中的标量对象及其初始化只是作为更广泛概念的一小部分。
如果 C 也遵循与 C++ 相同的规则,那不是很好吗?
我没看到。 C 和 C++ 是本质上不同的语言。他们对待
const
的方式也截然不同。
为什么C中const变量不需要初始化?
历史。
const
从一开始就在 C++ 中指定,并且使用满足了该语言的目标。 const
后来在 C 中指定了相关但不同的含义,以尽量减少现有的 C 代码兼容性问题。
由于 C 开始时没有
const
,它后来的包含更像是 read-only
修饰语,而不是 constant
修饰语。这使得现有编译器必须将 const
视为 nothing,因为写入 const
是未定义的行为。较新的编译器/代码可以利用 const
提供的优势。
const int a;
a = 5; // problem in C as code attempts to write `a`
// Really should be `const char *fred`, but allowed for backwards compatibility.
char *fred = "sally";
C++ 采用了更强大的方法并要求初始化。
因为 C 对程序员绝对有信心,并且确实允许他做很多事情,包括愚蠢的事情,例如:
int *x = NULL; x[4] = 12;
,编译时不会出现错误,甚至不会被许多编译器警告。
更准确地说,
const
只是程序员承诺变量不应该被修改,并且如果它有助于优化,编译器可以将其视为常量。但编译器永远不会强制执行任何运行时规则来禁止更改 const 值:
const a = 1;
int *ix = (int *) &a;
*ix = 2;
printf("a=%d\n", a); /* UB : could print 1 or 2 */
将在没有警告的情况下编译。但它会调用未定义的行为,因为您修改了声明为
const
的对象。
我相信不初始化
const
变量是允许的,因为当前的 C 规范并不禁止它!在以前的版本中,初始化始终是可选的。也许未来的版本可以强制自动变量初始化。
无论如何,全局或
static const
变量实际上是自动初始化的(根据C语言规范6.7.9 10):如果具有静态或线程存储持续时间的对象未初始化
显式地,则:...如果它具有算术类型,则将其初始化为(正或无符号)零; ...
因此,如果
static const a;
是全局的,那么 const a
和 a
一样完全有效,在这种情况下 a=0
。
我相信原因是惯例。
在 C 中,几乎没有任何类型的对象曾经需要被初始化,并且从来没有被需要被初始化。
const
物体只是又一种具有特殊特性的物体,为什么要例外呢?