Search

1.3 — A first look at variables, initialization, and assignment

Objects

C++ programs create, access, manipulate, and destroy objects. An object is a piece of memory that can be used to store values. You can think of an object as a mailbox, or a cubbyhole, where we can store and retrieve information. All computers have memory, called RAM (random access memory), that is available for programs to use. When an object is defined, a piece of that memory is set aside for the object.

Most of the objects that we use in C++ come in the form of variables.

Variables

A statement such as x = 5; seems obvious enough. As you might guess, we are assigning the value of 5 to x. But what exactly is x? x is a variable.

A variable in C++ is simply an object that has a name.

In this section, we are only going to consider integer variables. An integer is a number that can be written without a fractional component, such as -12, -1, 0, 4, or 27. An integer variable is a variable that holds an integer value.

In order to create a variable, we generally use a special kind of declaration statement called a definition (we’ll explain the precise difference between a declaration and a definition later). Here’s an example of defining variable x as an integer variable (one that can hold integer values):

When this statement is executed by the CPU, a piece of memory from RAM will be set aside (called instantiation). For the sake of example, let’s say that the variable x is assigned memory location 140. Whenever the program sees the variable x in an expression or statement, it knows that it should look in memory location 140 to get the value.

One of the most common operations done with variables is assignment. To do this, we use the assignment operator, more commonly known as the = symbol. For example:

When the CPU executes this statement, it translates this to “put the value of 5 in memory location 140”.

Later in our program, we could print that value to the screen using std::cout:

l-values and r-values

In C++, variables are a type of l-value (pronounced ell-value). An l-value is a value that has a persistent address (in memory). Since all variables have addresses, all variables are l-values. The name l-value came about because l-values are the only values that can be on the left side of an assignment statement. When we do an assignment, the left hand side of the assignment operator must be an l-value. Consequently, a statement like 5 = 6; will cause a compile error, because 5 is not an l-value. The value of 5 has no memory, and thus nothing can be assigned to it. 5 means 5, and its value can not be reassigned. When an l-value has a value assigned to it, the current value at that memory address is overwritten.

The opposite of l-values are r-values (pronounced arr-values). An r-value refers to values that are not associated with a persistent memory address. Examples of r-values are single numbers (such as 5, which evaluates to 5) and expressions (such as 2 + x, which evaluates to the value of variable x plus 2). r-values are generally temporary in nature and are discarded at the end of the statement in which they occur.

Here is an example of some assignment statements, showing how the r-values evaluate:

Let’s take a closer look at the last assignment statement above, since it causes the most confusion.

In this statement, the variable x is being used in two different contexts. On the left side of the assignment operator, “x” is being used as an l-value (variable with an address) in which to store a value. On the right side of the assignment operator, x is evaluated to produce a value (in this case, 7). When C++ evaluates the above statement, it evaluates as:

Which makes it obvious that C++ will assign the value 8 back into variable x.

For the time being, you don’t need to worry about l-values or r-values much, but we’ll return to them later when we start discussing some more advanced topics.

The key takeaway here is that on the left side of the assignment, you must have something that represents a memory address (such as a variable). Everything on the right side of the assignment will be evaluated to produce a value.

Initialization vs. assignment

C++ supports two related concepts that new programmers often get mixed up: assignment and initialization.

After a variable is defined, a value may be assigned to it via the assignment operator (the = sign):

C++ will let you both define a variable AND give it an initial value in the same step. This is called initialization.

A variable can only be initialized when it is defined.

Although these two concepts are similar in nature, and can often be used to achieve similar ends, we’ll see cases in future lessons where some types of variables require an initialization value, or disallow assignment. For these reasons, it’s useful to make the distinction now.

Rule: When giving variables an initial value, favor initialization over assignment.

Uninitialized variables

Unlike some programming languages, C/C++ does not initialize most variables to a given value (such as zero) automatically. Thus when a variable is assigned a memory location by the compiler, the default value of that variable is whatever (garbage) value happens to already be in that memory location! A variable that has not been given a known value (through initialization or assignment) is called an uninitialized variable.

Note: Some compilers, such as Visual Studio, will initialize the contents of memory when you’re using a debug build configuration. This will not happen when using a release build configuration.

Using the values of uninitialized variables can lead to unexpected results. Consider the following short program:

In this case, the computer will assign some unused memory to x. It will then send the value residing in that memory location to std::cout, which will print the value. But what value will it print? The answer is “who knows!”, and the answer may change every time you run the program. When the author ran this program with the Visual Studio 2013 compiler, std::cout printed the value 7177728 one time, and 5277592 the next.

If you want to run this program yourself, make sure you’re using a release build configuration (see section 0.6a -- Build configurations for information on how to do that). Otherwise the above program may print whatever value your compiler is initializing memory with (Visual Studio uses -858993460).

If your compiler won’t let you run this program because it flags variable x as an uninitialized variable, here is a possible solution to get around this issue:

Using uninitialized variables is one of the most common mistakes that novice programmers make, and unfortunately, it can also be one of the most challenging to debug (because the program may run fine anyway if the uninitialized value happened to get assigned to a spot of memory that had a reasonable value in it, like 0).

Fortunately, most modern compilers will print warnings at compile-time if they can detect a variable that is used without being initialized. For example, compiling the above program on Visual Studio 2005 express produced the following warning:

c:vc2005projectstesttesttest.cpp(11) : warning C4700: uninitialized local variable 'x' used

A good rule of thumb is to initialize your variables. This ensures that your variable will always have a consistent value, making it easier to debug if something goes wrong somewhere else.

Rule: Make sure all of your variables have known values (either through initialization or assignment).

Undefined behavior

Using the value from an uninitialized variable is our first example of undefined behavior. Undefined behavior is the result of executing code whose behavior is not well defined by the language. In this case, the C++ language doesn’t have any rules determining what happens if you use value of a variable that has not been given an known value. Consequently, if you actually do this, undefined behavior will result.

Code implementing undefined behavior may exhibit any of the following symptoms:

  • Your program produces an consistently incorrect result.
  • Your program produces different results every time it is executed.
  • Your program behaves inconsistently.
  • Your program seems like its working but produces incorrect results later in the program.
  • Your program crashes, either immediately or later.
  • Your program works on some compilers but not others.
  • Your program works until you change some other unrelated code.

Or, your code may actually produce the correct behavior anyway. The nature of undefined behavior is that you never quite know what you’re going to get, whether you’ll get it every time, and whether it’ll change when you make other changes.

C++ contains many cases that can result in undefined behavior if you’re not careful. We’ll ensure we point these out in future lessons. Take note of where these cases are and make sure you avoid them.

Rule: Take care to avoid situations that result in undefined behavior.

Quiz
What values does this program print?

6) What is undefined behavior?

Quiz Answers

To see these answers, select the area below with your mouse.

1) Show Solution

2) Show Solution

3) Show Solution

4) Show Solution

5) Show Solution

6) Show Solution

.

1.3a -- A first look at cout, cin, and endl
Index
1.2 -- Comments

251 comments to 1.3 — A first look at variables, initialization, and assignment

  • Therese McLeod

    Hi, me again, please ignore my inquery earlier today, I accidentally jumped forward, I now have my answer. Best, tutorial I’ve tried for coding, by the way, will make a donation, when I get paid again, thank you, I was beginning to worry I wouldn’t be able to afford to study this.
    Therese

  • It’s remarkable for me to have a web site, which is valuable for my knowledge.

    thanks admin

  • Usman

    int main()
    {
    using namespace std;
    …incomplete

    what does using namespace std; means??

  • Mahesh

    Alex,

        // define an integer variable named x
        int x;

    It’s not define an integer. It’s declare and integer variable named x. Please correct me if i am wrong. Thanks!

    • Alex

      It’s both a definition and a declaration. The fact that it’s a definition is more important, since definitions are more restrictive.

      • Mahesh

        Alex,

        int x; is just a declaration that tells compiler that i am going to use a variable in further program, but memory is not allocated. Memory will be allocated only when it is initialized like int x = 2; . Please correct me i am wrong thanks.

        • Alex

          You are wrong. int x defines an uninitialized integer variable named x. Memory is allocated for the variable, even though it’s uninitialized.

          I talk more about the difference between declarations and definitions, and when memory is allocated in future lessons.

  • Raj

    #include <iostream>

    int main()
    {
       using std::cout;
       cout << "Hello world!";
       return 0;
    }

    #include <iostream>

    int main()
    {
       using namespace std;
       cout << "Hello world!";
       return 0;
    }

    What will be the memory used difference between the above two program, will it be same or one will use more memory than the other and also what of the execution time.

    • Alex

      These two programs will compile to exactly the same thing, and run exactly the same. Just the top one uses a better programming style than the bottom one.

  • Alex

    Only const variables require initialization (we’ll cover const variables in a future chapter).

    No fundamental variables disallow assignment, although some custom types do (we’ll also cover this in a future chapter).

  • Sanja

    Hello! Can you tell me which variables require initialization and which disallow assignment? Thank you for creating this awesome website.

  • Pritam Das

    Why is this program printing the value 6? I understand that 5^3 might not have been understood by the IDE/compiler but it should have returned an error then? I wonder why is it executing the value as 6… (in CodeBlocks)

  • M.Mamdouh

    [#include <iostream>
    using namespace std;
    int main()
    {
        
        int x;
        /*int y;
        cout << "x value" << endl;
        cin >> x;
        cout << "y value" << endl;
        cin >> y;*/
        
        cout<< x << endl ;
        

        system ("pause");
        return 0;

    }]
    not working in release configuration

    • Mahesh

      Hey Mamdouh,

      Output your program should be garbage value because you commented below lines of code:

          /*int y;
          cout << "x value" << endl;
          cin >> x;
          cout << "y value" << endl;
          cin >> y;*/

      And why garbage value is you declared a integer variable but not initialized   int x; and your printing out.

  • Joel

    I’m using Visual Studio.
    I’ve tried the original code in the lesson;

    // #include "stdafx.h" // Uncomment if Visual Studio user
    #include <iostream>

    int main()
    {
        // define an integer variable named x
        int x;
        
        // print the value of x to the screen (dangerous, because x is uninitialized)
        std::cout << x;

        return 0;
    }

    I’ve tried;
    // #include "stdafx.h" // Uncomment if Visual Studio user
    #include <iostream>

    void doNothing(const int &x)
    {
    }

    int main()
    {
        // declare an integer variable named x
        int x;

        // trick the compiler into thinking this variable is used
        doNothing(x);

        // print the value of x to the screen (dangerous, because x is uninitialized)
        std::cout << x;
    }

    And I’ve tried a couple of other things from the comments section.

    Everything I try has the same result:
    1>---- Build started: Project: ConsoleApplication1, Configuration: Debug Win32 ----
    1>A task was canceled.
    1>A task was canceled.
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0skipped ==========

    Halp.

  • Kenny

    Fact: An integer IS NOT ALWAYS a whole number although every whole number is an integer

    Integers: -3,-2,-1,0,1,2,3
    Whole Numbers: 0,1,2,3,4

  • Steffen

    When I write the code in VC 2015 like this I get an C4700 error.

    (Because z is uninitialized)

    Why is that? Shouldn´t I still be able to run the program? Or am I doing something wrong?

    The Code:

    #include "stdafx.h"
    #include "iostream"

    int main()
    {
        int x = 5;
        x = x - 2;
        std::cout << x << std::endl;

        int y = x;
        std::cout << y << std::endl;

        std::cout << x + y << std::endl;

        std::cout << x << std::endl;

        int z;
        std::cout << z << std::endl;

        return 0;
    }

    And one more thing: When I push "Start without debugging", why does VC tells me the project is out of date and ask me if I like to run it anyway?

    Thanks

    • Alex

      Visual Studio treats uses of uninitialized variables as an error. Some other compilers treat it as a warning. There’s probably a way to make Visual Studio treat it as a warning instead of an error, but I wouldn’t advise changing it.

      As for the issue with projects being out of date, there are many reasons that can happen, none of which I’m able to help debug. 🙁 You’ll likely have more luck searching Google for a solution to that issue.

  • Ayush

    When I compiled my programme using debug build configuration in codeblocks then it showed the value 4309678 but when I shifted to release build configuration then it showed the value 0.

  • c++ begginer

    very good explanations its easy to understand

  • Vidya Moger

    When a variable is declared, does CPU set aside a piece of memory in stack? If so then I have a silly question here..
    As stack functionality is First In Last Out, how values pushed into stack are fetched because a program can use any variable at any point of time during execution? I dont know if my question makes any sense!!!!!!

    If not in stack, then which part of memory is used for programs?

    Thanks in advance 🙂

    • Alex

      This is covered much later in the tutorial. Short answer: global variables (which can be accessed any time) aren’t kept on a stack. Local variables (which can only be accessed in a limited scope) are kept on the stack.

  • Nyap

    x is uninitialized

  • mangix

    I wrote the above in the latest Code::Blocks (16.01) with gcc 5.1 on Windows 10 64 bit. I always got 0 instead of random output no matter in Debug or Release mode. Any ideas?

    • Alex

      Printing an unassigned variable results in undefined behavior. Undefined does not mean inconsistent. Your machine might always print 0, but another compiler might do something else entirely.

  • Nyap

    How much ram does one variable take up?

    • Alex

      It depends on the size of the variable. We discuss this in more detail in chapter 2.

      • Nyap

        k. also, could you be a bit more specific on what actually happens during instantiation? or do we also learn that in another lesson? thnx

        • Alex

          How variables get instantiated under the hood is a bit complex. All you really need to know at this point is that memory is set aside for the variable, so the variable can be used.

  • Mayur B.

    what I remember from C++ Primer, I believe

    is a declaration. And

    is definition(Declaration + Initialization).
    Please correct me if I’m wrong. Also I don’t know how much important these terms are? Please specify.
    -
    Mayur B.

  • Trung

    Hehe. My exercise for this topic.
    I can do it… YeYe

  • ak

    #include<iostream>

    using namespace std;

    int main ()

    {
        int v=0;
        char o=0.0;
        float p=0.0;

        cin >> v >> o >> p;

            return 0 ;
    }

    after taking first two inputs it terminates..why can’t i take the 3rd one?

  • Ellochain

    Hi there.

    I’m using the latest version of Code Blocks.
    Build target set to "Debug".

    Following code shows the value of two uninitialized variables x and y.

    Result :
    4285838 - 2752404

    I run it a few times over and always get the same numbers, which is reasonable like you explained above.
    Then I switch x and y in the cout expression like this :

    To my surprise the result remains unchanged :
    4285838 - 2752404

    So what’s going on here ?
    I thought the memory allocation happened as soon as the program encountered the variable declaration. But if that were true the numbers should have been switched just like the variables. Perhaps memory allocation happens only when the variable gets called the first time? Or is this a stack thing?

  • sajjadhussain

    Whats wrong with it?
    ITs showing the following error:
    1>ConsoleApplication2.cpp(15): error C2065: ‘endl’: undeclared identifier
    1>ConsoleApplication2.cpp(11): error C2065: ‘endl’: undeclared identifier

  • Joseph Daniel

    This doesn’t work and has the error : LNK1120 unresolved external at line 1
    and Severity Code Description Project File Line
    Error LNK2019 unresolved external symbol _WinMain@16 referenced in function “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) Test project E:Visual Studio ProjectsTest projectTest projectMSVCRTD.lib(exe_winmain.obj) 1

    • Alex

      It looks like you’re having a linker error where it can’t find your main() function for some reason. Is the file that this main() function is in added to your project?

      Try recreating your project and see if that works.

  • fateme

    which one we use is better? using name space std or std::?

    • Alex

      std:: is better from an ambiguity standpoint, but using can be easier to read. Which you use is situation dependent. I almost always use std::, and only use a using statement if I have a function that references std:: a lot of times, and for which all those references to std:: is impeding readability.

  • Danual

    Hi Alex!

    Sorry, but this may be confusing to some: "A variable can only be initialized when it is defined.", this implies that a variable must be initialized when the variable is defined, i.e. on the same line as defining it.

    • Alex

      > This implies that a variable must be initialized when the variable is defined, i.e. on the same line as defining it.

      It more than implies it -- it says it outright. 🙂 Variable must be initialized at the point they are defined. After the variable has been defined, you’re not initializing it, you’re assigning values to it. In many cases, the end result is the same. But we’ll see cases later where variables must be initialized (such as const values, or references) -- for this reason, it’s important to understand the distinction.

      What do you feel is confusing about the statement?

  • Kidane

    What is the difference if I put

    using namespace std;

    before main () function and inside main () function?

  • soham

    when will i be able to make a game of my own

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter