为啥返回未初始化的变量时编译器不报错?

Posted

技术标签:

【中文标题】为啥返回未初始化的变量时编译器不报错?【英文标题】:Why doesn't the compiler give an error when an uninitialized variable is returned?为什么返回未初始化的变量时编译器不报错? 【发布时间】:2014-01-24 09:13:13 【问题描述】:
#include <iostream>

using namespace std;

int weirdVariable = weirdVariable  + 1;
int main() 
  cout<< weirdVariable ;
  return weirdVariable ;

我只是想知道这个未初始化的变量如何不返回错误并返回 1。所以我的问题是,它如何/为什么返回值“1”。这个程序在逻辑上有效吗?还是有什么缺陷?

【问题讨论】:

因为全局变量未初始化。 我怀疑这个能不能编译成功。 @herohuyongtao 它确实可以编译,这就是我发布它的原因。尝试在这里编译它compileonline.com/compile_cpp11_online.php 它可以编译,虽然 return 1 是运行时抛出的错误代码 【参考方案1】:

它不是未初始化的。具有静态存储持续时间的变量(如全局变量)在任何进一步初始化之前首先被初始化为零。所以weirdVariable 的值是 1。

§3.6.2 [basic.start.init] 具有静态存储持续时间 (3.7.1) 或线程存储持续时间 (3.7.2) 的变量应在任何变量之前进行零初始化 (8.5)其他初始化发生。

如果您将wierdVariable 声明为main 的本地,它将未初始化。这会给你未定义的行为,因为对未初始化的对象执行左值到右值的转换(阅读:使用值)会产生未定义的行为。

§4.1 [conv.lval] 如果泛左值引用的对象 [...] 未初始化,则程序 必须进行此转换的行为未定义。

【讨论】:

但有时我会收到编译器的错误,说我没有初始化某些变量,所以这些变量不是静态的? 如果它们是本地指针,您需要初始化它们以便编译器知道最初分配给它们的内容 @kotAPI 对,它们不是静态的。 @DavidKernin 我使用的是 GNU GCC 4.7.2 版本。也许不同编译器的结果会有所不同。 @kotAPI 未定义的行为并不意味着它是无效的 C++。它是完全有效的 C++,但是当您运行可执行文件时,任何事情都可能发生。一个好的编译器能够警告你可能会遇到这种情况(我认为 GCC、clang 和 VS 都会这样做)。【参考方案2】:

静态和全局变量默认初始化为0,所以很正常

C 标准 ISO/IEC 9899:1999 又名 C99(和 C++)标准说必须如此。请参阅WG14 N1256 的第 6.7.8 节(“初始化”)中的第 10 项,了解确切的文本 (https://***.com/a/1294780/1938163)

顺便说一句:初始化静态变量是个好习惯,也只是为了使代码更具可读性!

static int myvar = 0;

不初始化它们的另一个缺点:如果编译器不遵循标准,你可能会遇到麻烦

对于NOT静态和NOT全局的局部变量,你可以跳过它们的初始化,但这会产生未定义的行为。不要真的依赖它。

【讨论】:

所以你的意思是说我已经通过将其设置为全局变量来将其声明为静态变量?但是当我在 main 方法中声明它时也会发生同样的情况.. 我忘了补充一点,静态变量和全局变量都是这样初始化的。固定 我同意,而且它非常依赖编译器,所以你不能依赖它。 @DavidKernin 是的,尤其是在游戏中。您不希望角色生成时的生命值为 0 而不是 100。:D 或 -100.. 只是说:)

以上是关于为啥返回未初始化的变量时编译器不报错?的主要内容,如果未能解决你的问题,请参考以下文章

VS2010 编写c语言变量为啥要初始化?

C++了解C++11新特性

C++了解C++11新特性

C++的变量为啥定义是要赋值?

java题 为啥//@Override才不报错

为啥 MATLAB 报告我的变量未初始化?