简体   繁体   English

为什么C ++中没有初始化(然后使用)的int不会返回错误?

[英]Why is it that an int in C++ that isnt initialized (then used) doesn't return an error?

I am new to C++ (just starting). 我是C ++的新手(刚开始)。 I come from a Java background and I was trying out the following piece of code that would sum the numbers between 1 and 10 (inclusive) and then print out the sum: 我来自Java背景,我正在尝试下面的一段代码,将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;
}

When I ran it it kept printing 32822 for the sum. 当我运行它时,它总是打印32822。 I knew the answer was supposed to be 55 and realized that its print the max value for a short (32767) plus 55. Changing 我知道答案应该是55并且意识到它打印最短值(32767)加上55.更改

int sum;

to

int sum = 0;

would work (as it should, since the variable needs to be initialized!). 会工作(因为它应该,因为变量需要初始化!)。 Why does this behavior happen, though? 但是为什么会发生这种情况呢? Why doesnt the compiler warn you about something like this? 为什么编译器不会警告你这样的事情? I know Java screams at you when something isnt initialized. 我知道当没有初始化时,Java会尖叫你。

Thank you. 谢谢。

Edit: Im using g++. 编辑:我正在使用g ++。 Here is the output from g++ --version: Im on Mac OS X and am using g++. 这是g ++ --version的输出:我在Mac OS X上运行并使用g ++。

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

Reading from an uninitialized variable results in undefined behavior and the compiler isn't required to diagnose the error. 从未初始化的变量读取会导致未定义的行为,并且不需要编译器来诊断错误。

Note that most modern compilers will warn you if you attempt to read an uninitialized variable. 请注意,如果您尝试读取未初始化的变量,大多数现代编译器都会发出警告。 With gcc you can use the -Wuninitialized flag to enable that warning; 使用gcc,您可以使用-Wuninitialized标志来启用该警告; Visual C++ will warn even at warning level 1. 即使在警告级别1,Visual C ++也会发出警告。

Because it's not part of the C++ standard. 因为它不是C ++标准的一部分。 The variable will just take whatever value is currently sitting in the memory it's assigned. 变量只会占用当前所分配的内存中的任何值。 This saves operations which can sometimes be unnecessary because the variable will be assigned a value later. 这样可以节省有时不必要的操作,因为稍后会为变量分配值。

It's interesting to note and very important for Java/.Net programmers to note when switching to C/C++. 值得注意的是,Java / .Net程序员在切换到C / C ++时需要注意并且非常重要。 A program written in C++ is native and machine-level. 用C ++编写的程序是本机和机器级的。 It is not running on a VM or a some other sort of framework. 它不是在VM或其他类型的框架上运行。 It is a collection of raw operations (for the most part). 它是原始操作的集合(大多数情况下)。 You do not have a virtual machine running in the background checking you variables and catching exceptions or segfaults for you. 您没有在后台运行的虚拟机检查变量并为您捕获异常或段错误。 This is a big difference which can lead to a lot of confusion in the way C++ handles variables and memory, as opposed to Java or a .Net language. 这是一个很大的区别,它可能导致C ++处理变量和内存的方式出现很多混乱,而不是Java或.Net语言。 Hell, in .Net all your integers are implicitly initialised to 0! 地狱,在.Net中,所有整数都被隐式初始化为0!

Consider this code fragment: 考虑以下代码片段:

int x;

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

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

Is x used uninitialized? x是未初始化的吗? How do you know? 你怎么知道的? What if there are preconditions to the code? 如果代码有前提条件怎么办?

These are hard questions to answer automatically, and enforcing initialization might be inefficient in some small way. 这些是自动回答的难题,并且执行初始化可能在某种程度上是低效的。


In point of fact modern compilers do a pretty good job of static analysis and can often tell if a variable is or might be used uninitialized, and they generally warn you in that case (at least if you turn the warning level up high enough). 事实上,现代编译器可以很好地进行静态分析,并且通常可以判断变量是否或者可能未被初始化使用,并且在这种情况下它们通常会警告您(至少如果您将警告级别提高到足够高)。 But c++ follows closely on the c tradition of expecting the programmer to know what he or she is doing. 但是c ++紧跟传统,期望程序员知道他或她在做什么。

It's how the spec is defined--that uninitialized variables have no guarantee's, and I believe the reason is that it has to do with optimizations (though I may be wrong here...) 这是规范的定义方式 - 未初始化的变量没有保证,我相信原因是它与优化有关(尽管我可能在这里错了......)

Many compilers will warn you, depending on the warning level used. 许多编译器会根据使用的警告级别向您发出警告。 I know by default VC++ 2010 warns for this case. 我知道默认情况下VC ++ 2010会警告这种情况。

What compiler are you using? 你用的是什么编译器? There is surely a warning level you can turn on via command-line switch that would warn you of this. 肯定会有一个警告级别,你可以通过命令行开关打开,警告你这一点。 Try compiling with /W3 or /W4 on Windows and you'll get 4700 or 6001 . 尝试在Windows上使用/ W3或/ W4进行编译,您将获得47006001

This is because C++ was designed as a superset of C, to allow easy upgrading of existing code. 这是因为C ++被设计为C的超集,以便轻松升级现有代码。 C works that way because it dates back to the 70s when CPU cycles were rare and precious things, so weren't wasted initialising variables when it might not be necessary (also, programmers were trusted to know that they'd have to do it themselves). C的工作方式是这样的,因为它可以追溯到70年代,当CPU周期是稀有和珍贵的东西时,所以在没有必要时不浪费初始化变量(同样,程序员被信任知道他们必须自己做)。

Obviously that wasn't really the case once Java appeared, so they found it a better tradeoff to spend a few CPU cycles to avoid that class of bugs. 显然,一旦Java出现就不是这样,所以他们发现花费几个CPU周期来避免这类错误是一个更好的权衡。 As others have noted though, modern C or C++ compilers will normally have warnings for this kind of thing. 正如其他人已经注意到的那样,现代C或C ++编译器通常会对此类事件发出警告。

Because C developers care about speed. 因为C开发人员关心速度。 Uselessly initializing a variable is a crime against performance. 无用地初始化变量是对性能的犯罪。

Detecting an uninitialized variable is a Quality-of-Implementation (QoI) issue. 检测未初始化的变量是实施质量(QoI)问题。 It is not mandatory, since the language standard does not require it. 它不是强制性的,因为语言标准不要求它。

Most compilers I know will actually warn you about the potential problem with an initialized variable at compile-time. 我知道的大多数编译器实际上会警告你在编译时初始化变量的潜在问题。 On top of that, compilers like MS Visual Studio 2005 will actually trap the use of an uninitialized variable during run-time in debug builds. 最重要的是,像MS Visual Studio 2005这样的编译器实际上会在调试版本的运行时捕获未初始化变量的使用。

So, what compiler are you using? 那么,你使用什么编译器?

Well, it depends on what compiler you use. 嗯,这取决于你使用的编译器。 Use a smart one. 使用聪明的。 :) http://msdn.microsoft.com/en-us/library/axhfhh6x.aspx :) http://msdn.microsoft.com/en-us/library/axhfhh6x.aspx

Initialising variables is one of the most important tenets of C/C++. 初始化变量是C / C ++最重要的原则之一。 Any types without a constructor should be initialised, period. 任何没有构造函数的类型都应该初始化,句点。 The reason for compiler not enforcing this is largely historical. 编译器不强制执行此操作的原因主要是历史性的。 It stems from the fact sometimes it's not necessary to init something and it would be wasteful to do so. 它源于这样一个事实:有时它不需要初始化某些东西,这样做会很浪费。

These days this sort of optimisation is best left to compiler and it's a good habit to always initialise everything. 这些天这种优化最好留给编译器,这是一个总是初始化所有内容的好习惯。 You can get the compiler to generate a warning for you as others suggested. 您可以让编译器像其他人建议的那样为您生成警告。 Also you can make it treat warnings as errors to further simulate javac behaviour. 此外,您可以将警告视为错误,以进一步模拟javac行为。

C++ is not a pure object oriented programming language. C ++不是纯粹的面向对象编程语言。 In C++ there is no implicit way of memory management and variable initialization. 在C ++中,没有隐式的内存管理和变量初始化方式。 If a variable is not initialized in C++ then it may take any value at runtime because the compiler does not understand such internal errors in C++. 如果变量未在C ++中初始化,则它可能在运行时获取任何值,因为编译器不理解C ++中的此类内部错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM