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

  • Karen

    Hi, Alex.

    I was able to run the Hello World program in chapter 0.6. I was also able to run it using the sample code (just commented out the previous lines) of not initializing. However, after initializing it, I encountered an error. I reverted it to the Hello World code, it produces the same error:

              === Build: Debug in HelloWorld (compiler: GNU GCC Compiler)…
    ld.exe    cannot open output file bin\Debug\HelloWorld.exe Permission…
              error: ld returned 1 exit status
              === Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 …

    What could be the problem?
    Thank you! 🙂

    • Alex

      It sounds like you’ve lost permission to overwrite HelloWorld.exe. The most obvious way this would happen is if HelloWorld.exe is still running. Make sure the program has closed (if you can’t figure out how, try rebooting). Other possibilities would be virus scanners or anti-malware interfering with writing the file.

  • Thirteen Spades

    Hi Alex;

    I put the following code into Visual Studio 2017, and it came up saying, -> C2143   syntax error: missing ‘;’ before ‘return’
    Also, how do I do the cool code thing you do in the comments with the colors?

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

    void doNothing(const int &x)
    {
    }

    int main()
    {
        // define an integer variable named x
        int x; // this variable is uninitialized

        doNothing(x); // make compiler think we’re using this variable

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

        return 0;
    }

  • Hema

    I am looking for a data type which accepts fraction as the input and then convert it into a decimal. Is there any?

    • Alex

      You can use a float or a double and do something like this:

      • Hema

        I will not be initialising the variable. The value will be given by the user during the run-time. Will double work in this case too?

        Thanks

        • Alex

          Kinda sorta not really. 🙂

          A double will store the decimal value, but it won’t convert a user-entered fraction into a decimal. To do that, you’ll need to write your own code.

          The initialization method works because the compiler will treat 5/3 as 5 divided by 3, which it will resolve to 1.66666… But it can only do that at compile time.

          • Hema

            1) Could you give a hint for writing the code to  convert a user-entered fraction into a decimal.

            2) I wrote the code in gedit and compiled it in Ubuntu terminal which supports c++11. It prints 1. How can I solve this problem?

            3) Do you get annoyed answering so many question everyday!?

            Thanks

            • Alex

              1) I’d recommend writing a class for this. Lesson 9.3 contains a sample Fraction class that could do this.
              2) Your code is doing integer division. You’d need to do something like this:

              We cover doubles and the difference between integer and floating point division in chapter 2.
              3) Sometimes. 🙂 But mostly for questions that have already been answered a thousand times. And for the remaining questions, mostly because answering questions takes away time from writing new stuff.

  • Robert Bristow

    Hello,
    I have been doing relatively minor coding in VBA and SQL for a few years now and seriously thinking about taking up C++.  So far these tutorials have been great.  In this section, even though the syntax is different the concept and output are right in line with VBA and mostly understandable to me.  However, I do wonder about possible subtleties.  Specifically, can the variables be more than one character.  X & Y are common variables to anywhere and I understand why you use them in your examples but is it safe to assume that something more descriptive could be used as well?  Say something like strcnt for string count.  Int strcnt = 5, for instance.  Then, for initialization, is zero always an acceptable value?  Are there any instances when a zero would cause an error?  I would not think it would cause any errors but would like to be clear on it as it seems that would logically be the safest practice.  

    Thanks

    • Alex

      Yes, variable names can be multiple characters. Variable naming conventions are covered in a few chapters. Initialization is a valid initialization value for all the fundamental types (like int, char, double, etc…), but may not be valid for user defined types, such as enums, structs, and classes.

  • Aditya

    Hi again Alex!

    I think that you need to mention that variables need to be declared in every function separately. It isn’t there and caused a lot of confusion in 1.4a excersise #5.

  • phong nguyen

    I’m using Visual Studio Community Ed. 2017. When I’m in Debug, a warning will pop up, unable to do anything else. When I’m in Release, uninitialized variables are initialized to 0.

    • Alex

      > When I’m in Debug, a warning will pop up, unable to do anything else

      What warning are you getting?

      > When I’m in Release, uninitialized variables are initialized to 0.

      This may be incidentally true, but is not guaranteed.

  • Ali

    I’ve seen many c++ tutorials
    all of them disappointed me, until I saw yours.
    I love how everything is explained in simple language without skipping stuff or over-complicating anything. Thank you.

  • Machinima Machinima

  • Ayush

    int main()
    {
        int x
        cout << x;
        return 0;
    }

    It gives an "C4700 uninitialized local variable" error in visual stdio 2015.

  • phong nguyen

    int x;
    std::cout << x  + "Abs";
    _______________________________________________
    Running this in **Release**
    output: Abs
    w/o string "Abs", output: 0
    _______________________________________________

    Running this in **Debug**
    output: "Error, variable x is being used without being initialized"
    ________________________________________________
    FYI, I am using visual studio community 2017 edition. I thought it was supposed to be the other way around where I get error in **Relase** and not **Debug**. THank you

    • Alex

      I would have expected you to get the same error in both cases, since that’s a compiler error, not a runtime error. Not sure why the behavior is different.

  • Nathan

    Hi,

    I’m running the following code below and it is only returning the value 0. I thought that it would print the memory location or something, I’m super confused. I’m using the release build on Visual Studio.

    Am I doing something wrong or is this just how C++ works now?

    Thanks,
    Nathan.

    • Alex

      It’s how C and C++ have always worked. Sending a variable to std::cout prints the value that the variable holds. In this case, since you haven’t initialized x, you’ll get an undefined value.

      If you want to print the memory location of x for some reason, you can use the & operator to get the address of x:

  • Ben Irwin

    I just noticed an English language error in the form of a missing "the".

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

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

  • Rrr

    #include <iostream>
    Int main ()
    {
    Int x;
    x=5;
    x=6;
    std::cout<<"x";
    Return 0;
    }
    It will first assign value 5 to x and then overwrite to 6 right???

  • jenifer

    Hey, can u help me answering this.  Which of the following C expressions are l-values? Why?

    1. x +2

    2. &x

    3. *&x

    4. &x + 2

    5. *(&x +2)

    6. &*y

    • Alex

      This sounds like a homework assignment. Rather than answering for you, let me give you a hint: if you can take the address of the result, it’s an l-value.

      With that knowledge, you should be able to determine your answers experimentally (i.e. try it).

  • Freddy G

    Awesome tutorial. I’m an old man trying to learn programming and I appreciate you for teaching this old dog new tricks!

  • My dear c++ Teacher,
    Please let me say what I understand,  and what not, regarding "Initialization vs. assignment".
    I understand that C++ will let you both define a variable AND give it an initial value in the SAME STEP. It follows, when a variable is defined and THEN assigned a number, is NOT initialized, is uninitialized. It is defined and assigned (a number) in two steps (statements).
    When it is not assigned a number, either by "assignment" or by "initialization", should be said "unassigned".
    "Uninitialized" is meant not initialized, but may be defined and assigned in two steps.
    With regards and friendship.

    • Alex

      We colloquially use the term “uninitialized” to mean the variable has not been given a value yet (by any means). If the variable is later assigned a value, we say the variable is no longer uninitialized, even though we gave it a value via assignment.

  • Dennis

    Hi,

    class variables of for example std::string can have default initialization, see

    http://en.cppreference.com/w/cpp/language/default_initialization

    I know this will be talked about later in this tutorial. People might get the impression that all variables are not initialized at all. Maybe add a note that this is not always the case.

    • Alex

      I updated this lesson to note that “most” variable don’t self-initialize. Although it’s certainly true that some types of variable do self-initialize, I don’t think that’s particularly relevant to know at this point in the tutorial, since we don’t cover those types of variables for quite some time. For now, it’s better to act as if no variables self-initialize, and then we’ll cover those other cases later.

  • My dear c++ Teacher,
    Please let me following comment:
    First two sentences are:
    "C++ programs create, access, manipulate, and destroy objects. An object is a piece of memory that can be used to store values."
    It means c++ programs eventually destroy pieces of memory!
    By the way let me wish you enjoy a Hawaiian pizza and a pint of Newcastle.
    With regards and friendship.

  • Someone confused with C++

    Okay, so I had failures going with the code. It looks like that:

    But it was still giving me two errors:
    C2065: "cout": undeclared identifier
    C2065: "endl": undeclared identifier
    How do I solve it? I’ve sifted through the comment section, but still no solution.

  • My dear c++ Teacher,
    Please let me say you Visual Studio 2017 behavior when variable "x" is uninitialized.
    A. After pressing "Build Solution":
    1. Seven lines, three of them are Addresses in hard disk. First address is followed by
    "warning C4700: uninitialized local variable ‘x’ used"
    2. Last line is
    "Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped".
    B. After pressing "Start Without Debugging":
    Console window is appeared just saying (in french) "press any key to continue…"
    With regards and friendship.

    • Alex

      Yes, your compiler is giving you a warning that you are using an uninitialized local variable. This is not an error though, so the compilation succeeds. Your program may not perform as you expect though.

  • My dear c++ Teacher,
    Please let me send you following program for your quiz, with std::endl after every output, so that numbers be on different lines.

    With regards and friendship.

  • Billy Bob Joe

    hi,
      I was wondering how to initialize strings?

    • Alex

      It depends on what kind of string you’re referring to. Strings in C++ are a little more complicated than in some other languages. I talk about std::string in chapter 4, and C-style strings in chapter 6.

Leave a Comment

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