为什么 const 变量不需要在 C 中初始化?
Why const variable need not to be initialized in C?
const
C++ 中的变量必须初始化意味着 uninitialized const variable
是不可能的,这是一个编译器错误。但是为什么在C语言中也不一样呢?
考虑以下编译良好 C 的程序:
#include <stdio.h>
int main()
{
const int a;
}
允许uninitialized const
的原因是什么?如果 C 也遵循与 C++ 相同的规则,那不是很好吗?每次调用函数都要初始化局部const变量,初始化耗时,是不是性能问题?
历史。
const
从一开始就在 C++ 中指定,使用符合该语言的目标。 const
后来在 C 中指定,但具有相关但不同的含义,以最大限度地减少现有的 C 代码兼容性问题。
因为 C 开始时没有 const
,它后来的包含更像是一个 read-only
修饰符而不是 constant
修饰符。这允许现有的编译器将 const
视为 nothing 因为写入 const
是未定义的行为。较新的 compilers/code 可以利用 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++ 采用了更强的方法并要求初始化。
另见 const in C vs const in C++
我认为原因是惯例。
在 C 语言中,几乎没有任何一种对象 需要 初始化,而且从来没有 需要 初始化。
const
物体只是多了一种物体,有一个特殊的特性,为什么要例外呢?
因为 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 规范并不禁止它!在以前的版本中,初始化始终是可选的。也许未来的版本可以强制初始化自动变量
无论如何,全局或静态 const 变量实际上会自动初始化(根据 C 语言规范 6.7.9 10):如果具有静态或线程存储持续时间的对象未初始化
明确地,那么: ...如果它具有算术类型,则将其初始化为(正数或无符号)零; ...
所以 static const a;
和 const a
一样完全有效,如果 a
是全局的,在这种情况下 a=0
.
除其他外,差异可能源于 C 语言 一般 中明显更宽松的初始化方法,而不仅仅是 const
对象。例如这段代码在C++中是非法的
goto over;
int a = 5;
over:;
因为它跳转到 a
的范围绕过它的初始化。同时在 C 中,这段代码是完全合法的,变量 a
在 over:
处具有不确定的值。
同样的逻辑也适用于您的 const int a
声明。 C语言简单地认为一个未初始化的对象没什么大不了的,即使在以后不可能再将它设置为确定值的情况下。
C++ 中更严格的初始化要求的主要原因是在语言中引入了非平凡的初始化(构造函数),即无法有意义地绕过的初始化。标量对象及其在 C++ 中的初始化只是被标记为更广泛概念的一小部分。
Wouldn't it be nice If C also follows same rule as C++ does?
我没看到。 C 和 C++ 是本质上不同的语言。他们对待 const
的方式也大不相同。
const
C++ 中的变量必须初始化意味着 uninitialized const variable
是不可能的,这是一个编译器错误。但是为什么在C语言中也不一样呢?
考虑以下编译良好 C 的程序:
#include <stdio.h>
int main()
{
const int a;
}
允许uninitialized const
的原因是什么?如果 C 也遵循与 C++ 相同的规则,那不是很好吗?每次调用函数都要初始化局部const变量,初始化耗时,是不是性能问题?
历史。
const
从一开始就在 C++ 中指定,使用符合该语言的目标。 const
后来在 C 中指定,但具有相关但不同的含义,以最大限度地减少现有的 C 代码兼容性问题。
因为 C 开始时没有 const
,它后来的包含更像是一个 read-only
修饰符而不是 constant
修饰符。这允许现有的编译器将 const
视为 nothing 因为写入 const
是未定义的行为。较新的 compilers/code 可以利用 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++ 采用了更强的方法并要求初始化。
另见 const in C vs const in C++
我认为原因是惯例。
在 C 语言中,几乎没有任何一种对象 需要 初始化,而且从来没有 需要 初始化。
const
物体只是多了一种物体,有一个特殊的特性,为什么要例外呢?
因为 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 规范并不禁止它!在以前的版本中,初始化始终是可选的。也许未来的版本可以强制初始化自动变量
无论如何,全局或静态 const 变量实际上会自动初始化(根据 C 语言规范 6.7.9 10):如果具有静态或线程存储持续时间的对象未初始化 明确地,那么: ...如果它具有算术类型,则将其初始化为(正数或无符号)零; ...
所以 static const a;
和 const a
一样完全有效,如果 a
是全局的,在这种情况下 a=0
.
除其他外,差异可能源于 C 语言 一般 中明显更宽松的初始化方法,而不仅仅是 const
对象。例如这段代码在C++中是非法的
goto over;
int a = 5;
over:;
因为它跳转到 a
的范围绕过它的初始化。同时在 C 中,这段代码是完全合法的,变量 a
在 over:
处具有不确定的值。
同样的逻辑也适用于您的 const int a
声明。 C语言简单地认为一个未初始化的对象没什么大不了的,即使在以后不可能再将它设置为确定值的情况下。
C++ 中更严格的初始化要求的主要原因是在语言中引入了非平凡的初始化(构造函数),即无法有意义地绕过的初始化。标量对象及其在 C++ 中的初始化只是被标记为更广泛概念的一小部分。
Wouldn't it be nice If C also follows same rule as C++ does?
我没看到。 C 和 C++ 是本质上不同的语言。他们对待 const
的方式也大不相同。