为什么C++;未初始化(然后使用)的不';不返回错误吗? 我是C++新手(刚刚开始)。我来自Java背景,我正在尝试以下代码,将数字相加到1和10之间(包括1和10),然后打印出总和: /* * File: main.cpp * Author: omarestrella * * Created on June 7, 2010, 8:02 PM */ #include <cstdlib> #include <iostream> using namespace std; int main() { int sum; for(int x = 1; x <= 10; x++) { sum += x; } cout << "The sum is: " << sum << endl; return 0; }

为什么C++;未初始化(然后使用)的不';不返回错误吗? 我是C++新手(刚刚开始)。我来自Java背景,我正在尝试以下代码,将数字相加到1和10之间(包括1和10),然后打印出总和: /* * File: main.cpp * Author: omarestrella * * Created on June 7, 2010, 8:02 PM */ #include <cstdlib> #include <iostream> using namespace std; int main() { int sum; for(int x = 1; x <= 10; x++) { sum += x; } cout << "The sum is: " << sum << endl; return 0; },c++,primitive-types,C++,Primitive Types,到 将起作用(因为变量需要初始化!)。然而,为什么会发生这种行为?为什么编译器不警告你类似的事情?我知道当某些东西没有初始化时,Java会向你尖叫 多谢各位 编辑: 我使用g++。以下是g++--版本的输出: Mac OS X上的即时消息和使用g++的am nom24837c:~ omarestrella$ g++ --version i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) 从未初始化的变量读取会导致未

将起作用(因为变量需要初始化!)。然而,为什么会发生这种行为?为什么编译器不警告你类似的事情?我知道当某些东西没有初始化时,Java会向你尖叫

多谢各位

编辑: 我使用g++。以下是g++--版本的输出:
Mac OS X上的即时消息和使用g++的am

nom24837c:~ omarestrella$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)

从未初始化的变量读取会导致未定义的行为,并且不需要编译器来诊断错误


请注意,如果您试图读取未初始化的变量,大多数现代编译器都会发出警告。使用gcc,您可以使用-Wuninitialized标志来启用该警告;Visual C++即使在警告级别1也会发出警告。

因为它不是C++标准的一部分。变量将只接受它所分配的内存中当前存在的任何值。这样可以节省一些操作,这些操作有时是不必要的,因为变量稍后将被赋值


注意这一点很有趣,对于Java/.Net程序员来说,在切换到C/C++时注意这一点非常重要。用C++编写的程序是本地的和机器级的。它不是在VM或其他某种框架上运行的。它是原始操作的集合(大部分)。您没有在后台运行的虚拟机为您检查变量并捕获异常或SEGFULTS。这是一个很大的差异,这可能导致C++在处理变量和内存方面的混乱,而不是java或.NET语言。在.Net中,所有整数都隐式初始化为0

规范是如何定义的——未初始化的变量没有保证,我相信原因是它与优化有关(尽管我在这里可能错了…)


根据使用的警告级别,许多编译器会向您发出警告。我知道默认情况下VC++2010会针对这种情况发出警告。

好吧,这取决于您使用的编译器。使用智能手机。:)
您使用的编译器是什么?当然,您可以通过命令行开关打开一个警告级别来警告您。尝试在Windows上使用编译,您会得到or。

初始化变量是C/C++最重要的原则之一。任何没有构造函数的类型都应该初始化,句号为。编译器不强制执行此操作的原因主要是历史原因。它源于这样一个事实:有时不需要初始化某些东西,这样做是浪费


现在这种优化最好留给编译器来做,并且总是初始化所有东西是一个好习惯。您可以让编译器按照其他人的建议为您生成警告。此外,您可以将警告视为错误,以进一步模拟Javac行为。

< P>这是因为C++被设计为C的超集,以便允许升级现有代码。C的工作原理是这样的,因为它可以追溯到70年代,那时CPU周期是罕见而宝贵的东西,所以在不必要的时候初始化变量不会浪费时间(同样,程序员被信任知道他们必须自己去做)


显然,Java出现后情况并非如此,因此他们发现花几个CPU周期来避免这类错误是一个更好的折衷办法。正如其他人注意到的,现代C或C++编译器通常会对这种事情发出警告。

< P>因为C开发人员关心速度。无效地初始化变量是对性能的犯罪。

检测未初始化的变量是实现质量(QoI)问题。它不是强制性的,因为语言标准不要求它

我知道的大多数编译器实际上会在编译时警告您初始化变量的潜在问题。除此之外,像MS Visual Studio 2005这样的编译器实际上会在调试构建的运行时捕获未初始化变量的使用


那么,您使用的编译器是什么?

请考虑以下代码片段:

int x;

if ( some_complicated_condition ) {
   x = foo;
} else if ( another_condition ) {
   // ...
   if ( yet_another_condition ) x = bar;    
} else {
   return;
}

printf("%d\n",x);
x
是否未初始化使用?你怎么知道的?如果代码有先决条件呢

这些都是很难自动回答的问题,而强制执行初始化可能在某种程度上效率低下



事实上,现代编译器在静态分析方面做得相当好,通常可以判断变量是否未初始化,并且通常会在这种情况下向您发出警告(至少在您将警告级别调高到足够高的情况下)。但是C++遵循C++传统,期望程序员知道他或她在做什么。 在C++中,没有隐式的内存管理方式和变量初始化。
如果变量在C++中没有初始化,那么它可能在运行时取任何值,因为编译器不理解C++中的这些内部错误。

注意到java对于未定义行为的机会远少,代价是灵活性降低,需要更多的编译时和运行时检查。如果您在示例中更改它,它将帮助我们更快、更容易地回答问题:如果您将警告级别设置得足够高,DMost编译器将向您发出警告。如果您按照大多数组织的要求(或我工作过的组织)执行操作,您将设置ccompiler,将警告视为错误,因此它也不会编译。请注意,只有基本类型(int、long、char、pointers..)需要此显式初始化。类不需要它。例如,您声明了一个空字符串“std::string str;”不是“std::string str=”“;”这就是为什么我总是用-Wall编译。是的,用g++-Wall才是真理!我应该在Mac上提到Im并使用Netbeans:)我相信
nom24837c:~ omarestrella$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)
int x;

if ( some_complicated_condition ) {
   x = foo;
} else if ( another_condition ) {
   // ...
   if ( yet_another_condition ) x = bar;    
} else {
   return;
}

printf("%d\n",x);