为什么C中const变量不需要初始化?

问题描述 投票:0回答:4
C++ 中的

const
变量必须初始化意味着
uninitialized const variable
是不可能的,并且这是一个编译器错误。但为什么在C语言中也不一样呢? 考虑以下可以编译良好 C 的程序:

#include <stdio.h>
int main()
{
    const int a;
}

允许

uninitialized const
的理由是什么?如果 C 也遵循与 C++ 相同的规则,那不是很好吗?是否出于性能考虑,每次调用函数时都需要初始化局部 const 变量并且初始化需要时间?

c initialization constants
4个回答
11
投票

这种差异可能源于,除其他外,C 语言中的初始化方法一般而言更加宽松,而不仅仅是针对

const
对象。例如,这段代码在C++中是非法的

goto over;
int a = 5;
over:;

因为它绕过初始化跳转到

a
的范围。同时,在 C 中,这段代码是完全合法的,变量
a
over:
处具有不确定的值。

同样的逻辑也适用于您的

const int a
声明。 C 语言只是认为未初始化的对象没什么大不了的,即使在以后不再可能将其设置为确定值的情况下也是如此。

C++ 中更严格的初始化要求的主要原因是在语言中引入了重要的初始化(构造函数),即无法有意义地绕过的初始化。 C++ 中的标量对象及其初始化只是作为更广泛概念的一小部分。

如果 C 也遵循与 C++ 相同的规则,那不是很好吗?

我没看到。 C 和 C++ 是本质上不同的语言。他们对待

const
的方式也截然不同。


5
投票

为什么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 中的 const 与 C++ 中的 const


1
投票

因为 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


0
投票

我相信原因是惯例。

在 C 中,几乎没有任何类型的对象曾经需要被初始化,并且从来没有被需要被初始化。

const
物体只是又一种具有特殊特性的物体,为什么要例外呢?

© www.soinside.com 2019 - 2024. All rights reserved.