为什么零初始化不是C ++中未初始化变量的默认值?是否有编译器选项可以强制执行?

Ben*_*Ben 3 c++

在我所知的大多数语言中,标量类型变量如果未在代码中初始化,则默认情况下会被零初始化。为什么在c / c ++中不会发生这种情况?我能想到的唯一原因是性能,但是

  • 如果我初始化它,确实会消耗性能吗?
  • 有未定义的行为是否更可取?
  • 如果我想避免未定义的行为,则无论如何都必须对其进行初始化,那么我赢了什么?

如果这可能是性能问题,显式地告诉编译器不对变量进行零初始化会不会更容易?

最后一个我的问题:是否有一个gcc选项告诉编译器默认为零初始化?

Fra*_*eux 16

C ++的创始原则之一是不强迫开发人员为自己不使用的东西付费。如果您编写类似的代码,int x; x = 1;则无需为的零初始化支付费用x,即使该开销恰好很小。

编辑:关于您的其他两点

有未定义的行为是否更可取?

在语言中,未定义的行为不一定是一件坏事(两种方式都可以争论)。如果您编写导致它的代码,那肯定是一件坏事。值得注意的是,它为实施人员提供了更多自由并实现了重要的优化。

如果我想避免未定义的行为,则无论如何都必须对其进行初始化,那么我赢了什么?

拥有未初始化的变量不是未定义的行为。尝试从其中读取是一种不确定的行为。


met*_*tal 5

向下端:因为未初始化值的潜在的错误。

优点

  1. 效率。如果您不需要它,则无需为此付费。
  2. 编译器不会添加有关正确的init值的假设。在对OP的注释中,每个@chris都会引起错误的安全感,因为0并不总是正确的初始化值。如果以-1开头,那么0是错误的。

缓解措施

  1. 使用构造函数初始化您的非POD类型
  2. 使用“ 几乎总是自动 ”在声明时强制初始化。(或正如@Peter在评论中所指出的那样,请使用显式类型,但在声明变量之前必须先对其进行正确初始化。这由AAA隐含,但是AAA使得更容易出错,因为您不会偶然忘记初始化因为初始化也包含类型信息。)
  3. 提高编译器警告。对于gcc,请使用-Wall -Werror,其中包含-Wuninitialized,然后在未初始化的值时将出错。

起源:在C的旧时代,所有声明都首先出现在初始化之前。比较K&R书中的以下示例

int main(void)
{
  double sum, atof(char s[]);
  char line[MAXLINE];
  int getline(char line[], int max);

  sum = 0;
  while (getline(line, MAXLINE) > 0)
    printf("\t%g\n", sum += atof(line));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这方面,C ++保留了与C的兼容性,但这是不幸的默认行为。