views:

358

answers:

11

I am new to C++ (just starting). 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:

/* 
 * 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. I knew the answer was supposed to be 55 and realized that its print the max value for a short (32767) plus 55. Changing

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.

Thank you.

Edit: Im using g++. Here is the output from g++ --version: Im on Mac OS X and am using g++.

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

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; Visual C++ will warn even at warning level 1.

James McNellis
This is why I always compile with -Wall.
Duracell
Yeah, with g++ -Wall is the way of truth!
Alan
+14  A: 

Because it's not part of the C++ standard. 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++. A program written in C++ is native and machine-level. It is not running on a VM or a some other sort of framework. 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. Hell, in .Net all your integers are implicitly initialised to 0!

Duracell
+2  A: 

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.

Alan
+1  A: 

Well, it depends on what compiler you use. Use a smart one. :) http://msdn.microsoft.com/en-us/library/axhfhh6x.aspx

young
I shouldve mentioned Im on a Mac and use Netbeans :)
omizzle
+2  A: 

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.

jeffamaphone
I believe that gcc/g++ is what is used on OS X. From the comments above, I believe that -Wall would be what I should use.
omizzle
Yes; you are correct.
jeffamaphone
A: 

Initialising variables is one of the most important tenets of 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.

Igor Zevaka
+2  A: 

This is because C++ was designed as a superset of C, to allow easy upgrading of existing code. 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).

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. As others have noted though, modern C or C++ compilers will normally have warnings for this kind of thing.

Peter
+2  A: 

Because C developers care about speed. Uselessly initializing a variable is a crime against performance.

johnnycrash
@Johnnycrash I think "C care about speed" is more exact than "C developers".
Allopen
I stand corrected. The code I have been optimizing for the last few days will be admitted as evidence.
johnnycrash
+2  A: 

Detecting an uninitialized variable is a Quality-of-Implementation (QoI) issue. 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.

So, what compiler are you using?

AndreyT
Im on Mac OS X and am using g++.g++ --version: i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)
omizzle
+5  A: 

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? 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.

dmckee
A: 

C++ is not a pure object oriented programming language. In C++ there is no implicit way of memory management and variable initialization. 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++.

Sonali