0

I'm new to C++, and am having some problems understanding why my integer year is coming out as -2. I did not set a value to it as far as i can tell.

#include <iostream>
#include <stdlib.h>                         

using namespace std;

int main()                                 
{
    int age;                                
    string mystring;                         
    mystring = "Did you enjoy the game?";   
    int day, month;
    int year;

    cout << year << "\n";

    cout << "Game Over!" << endl;           

    cout << "You Lose!" << endl;            
    cout << mystring << endl;             
    cout << "What was the best part of the game? \n";  
    cout << "Was it the graphics? \n";                  


    cout << "Please put in your age: ";
    cin >> age;                                        
    cout << "The age you put in is: " << age << endl;

    cout << "Please put in the day (1-31) and the month (1-12) in thier numerical values: " <<        endl;
    cin >> day >> month;
    cout << "So today is " << month << "/" << day;

    system("Pause");                        
}

Everything is working fine. Thanks for everything guys. I thought it would go automatically to 0 if it had no value, but now i see that it does not. Thanks again.

  • Or it will not be initialised at all and you'll get whatever was left at that address at run time. You're not really asking a question though. If you want to force the value just do `int year = 2014;` – zeFrenchy Sep 23 '14 at 14:21

2 Answers2

3

The value of year has not been yet initialized, and when the compiler reads an uninitialized variable it leads to undefined behavior. It could be any value in the memory, really. it all depends on your computer and the compiler.

Doing so is always a BAD idea because it will result in faulty code,
as a rule of thumb always initialize the value before you call the variable.

Also keep in mind in some compilers it is mandatory to include #include <string>(when using strings) or else your code won't run.

Community
  • 1
  • 1
Chantola
  • 540
  • 1
  • 5
  • 18
  • It's worse. Any random-value would be fairly harmless, what we actually have is full UB. – Deduplicator Sep 23 '14 at 14:28
  • Adding `#include ` is certainly a good idea, but it may not be necessary. At least on my system, `` seems to include `` implicitly (which makes sense, since it declares operators that act on `std::string`). I'm not sure whether it's required to work that way. – Keith Thompson Sep 23 '14 at 14:29
  • Slight correction if the value is coming up as either a 0 or ~0(not 0, this is the number with all bits filled in as 1) than the compiler is auto initializing the value. Otherwise the value you are seeing is information that had previously been stored in that memory position. – Zachary Kraus Sep 23 '14 at 14:30
  • @KeithThompson it depends on the compiler, I think. My compiler incluing string is a neccesity, thank you for pointing this out! – Chantola Sep 23 '14 at 14:30
  • 2
    @KeithThompson if you use `std::string` you should include , if you want to avoid problems (either by porting your code or even upgrading your compiler) you should not deduce rules by compiler behaviour – Slava Sep 23 '14 at 14:34
  • @Deduplicator you talked about how it is even worse, what we actually have is full UB. i have never heard about such behavior, I would be pleased if you could explain what you mean in greater detail. Thank you for your time. – Chantola Sep 23 '14 at 14:38
  • @Slava: Agreed, I didn't mean to imply otherwise. (I just took a quick look at the "Library introduction" section of the C++ standard, and I'm still not sure whether referring to `std::string` after `#include ` is required to work, required to be diagnosed, or implementation-defined. – Keith Thompson Sep 23 '14 at 14:42
  • @Chantola: See 4.1 lvalue-to-rvalue-conversion [conv.lval], that section spells it out. – Deduplicator Sep 23 '14 at 14:43
  • Do you have a citation for that last paragraph, either an example of a compiler that requires `#include ` or a citation from the C++ standard? (In C, a standard header *may not* introduce the contents of another standard header; C++ may have different rules.) – Keith Thompson Sep 23 '14 at 14:46
  • @KeithThompson: It's enough that the standard does not mandate `` has to include ``, keeping in mind that everything working on `std::basic_string<...>` or other symbols from `string` is a template, and thus a forward-declaration is enough. – Deduplicator Sep 23 '14 at 14:56
  • 1
    @KeithThompson On my Microsoft Visual Studio C++ 2013, I get the following error running the corrected program without the string header: error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion) this error is eliminated when I #include and upon further research, this error has happened often when the #include was not included. Hope this helps. – Chantola Sep 23 '14 at 14:56
  • Yes, it helps. I'm still interested in knowing what the standard says about this. I'll be dismayed, but not necessarily surprised, if it turns out that the validity of the OP's code is implementation-defined or unspecified. – Keith Thompson Sep 23 '14 at 15:02
  • 1
    @KeithThompson: Please read 17.6.5.2 Headers [res.on.headers]: C headers () may only include the corresponding C++ header (), but C++ headers may include any and all other C++ headers. Also, as I said, there's no explicit or implicit requirement for to include . – Deduplicator Sep 23 '14 at 15:47
  • @Deduplicator: Thanks, that's exactly what I was looking for (I just didn't read far enough). – Keith Thompson Sep 23 '14 at 16:24
0

In C++ you do not pay for what you do not use. This means there are a places in the language where the compiler could do more, but it doesn't in case the developers didn't actually want those things done (for performance or other reasons).

This (initialization of variables) is one of those cases: if you do not explicitly assign a value to a POD variable (or call a constructor on it) you cannot assume it will have any value. What the compiler does in this case is assign stack memory for year and the variable becomes initialized with whatever was in memory on the stack, at that location (which in your case was -2, when interpreted as an int).

Note: another example of this compiler policy is when you delete dynamically allocated memory: the poointer usually remains filled with the old address (which is no longer valid).

utnapistim
  • 26,809
  • 3
  • 46
  • 82
  • What if compiler does not assign any memory for this variable? – Slava Sep 23 '14 at 14:30
  • @Slava: That's in fact quite common in optimized builds. You'll still get random results. The instructions will end up using some of part of memory, or possible CPU registers. Really impossible to predict. – MSalters Sep 23 '14 at 14:50
  • @MSalters I agree, I point that answer's explanation could be incorrect, I think that explanation how that value obtained is completely unnesessary – Slava Sep 23 '14 at 14:59