【问题标题】:Why const variable need not to be initialized in C?为什么 const 变量不需要在 C 中初始化?
【发布时间】:2015-09-09 07:22:24
【问题描述】:

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

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

允许uninitialized const的原因是什么?如果 C 也遵循与 C++ 相同的规则,那不是很好吗?是不是因为性能问题,每次调用函数都需要初始化局部 const 变量,初始化需要时间?

【问题讨论】:

  • 版主说明:请使用 cmets 请求澄清/讨论所提出的问题。谢谢。

标签: c initialization constants


【解决方案1】:

历史。

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++ 采用了更强的方法,需要初始化。

另见const in C vs const in C++

【讨论】:

    【解决方案2】:

    除其他外,差异可能源于 C 语言中的初始化方法明显更宽松一般,不仅仅是const 对象。例如,这段代码在 C++ 中是非法的

    goto over;
    int a = 5;
    over:;
    

    因为它跳过了它的初始化跳转到a 的范围。同时在 C 中,这段代码是完全合法的,变量aover: 处具有不确定的值。

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

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

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

    我没看到。 C 和 C++ 是完全不同的语言。他们对待const 的方式也完全不同。

    【讨论】:

      【解决方案3】:

      因为 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 标准没有提供可能发生此类事情的方法,但没有理由禁止可能通过此类方法变得有用的构造。
      【解决方案4】:

      我相信原因是惯例。

      在 C 中,几乎没有任何一种对象需要被初始化,也从来没有被需要初始化。

      const对象只是又一种具有一个特殊特性的对象,为什么要对它们进行例外处理?

      【讨论】:

        猜你喜欢
        • 2018-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-18
        • 2015-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多