Search

2.1 — Fundamental variable definition, initialization, and assignment

Addressing memory

This lesson builds directly on the material in the section “1.3 -- A first look at variables“.

In the previous lesson on variables, we talked about the fact that variables are names for a piece of memory that can be used to store information. To recap briefly, computers have random access memory (RAM) that is available for programs to use. When a variable is defined, a piece of that memory is set aside for that variable.

The smallest unit of memory is a binary digit (bit), which can hold a value of 0 or 1. You can think of a bit as being like a traditional light switch -- either the light is off (0), or it is on (1). There is no in-between. If you were to look at a random segment of memory, all you would see is …011010100101010… or some combination thereof. Memory is organized into sequential units called addresses. Similar to how a street address can be used to find a given house on a street, the memory address allows us to find and access the contents of memory at a particular location. Perhaps surprisingly, in modern computers, each bit does not get its own address. The smallest addressable unit of memory is a group of 8 bits known as a byte.

The following picture shows some sequential memory addresses, along with the corresponding byte of data:

Memory Addressing

Because all data on a computer is just a sequence of bits, we use a data type (often called a “type” for short) to tell us how to interpret the contents of memory in some meaningful way. You have already seen one example of a data type: the integer. When we declare a variable as an integer, we are telling the compiler “the piece of memory that this variable addresses is going to be interpreted as a whole number”.

When you assign a value to a data type, the compiler and CPU take care of the details of encoding your value into the appropriate sequence of bits for that data type. When you ask for your value back, your number is “reconstituted” from the sequence of bits in memory.

There are many other data types in C++ besides the integer, most of which we will cover shortly. As shorthand, we typically refer to a variable’s “data type” as its “type”.

Fundamental data types

C++ comes with built-in support for certain data types. These are called fundamental data types (in the C++ specification), but are often informally called basic types, primitive types, or built-in types.

Here is a list of the fundamental data types, some of which you have already seen:

Category Types Meaning Example Notes
boolean bool true or false true
character char, wchar_t, char16_t, char32_t a single ASCII character ‘c’ char16_t, char32_t are C++11 only
floating point float, double, long double a number with a decimal 3.14159
integer short, int, long, long long a whole number 64 long long is C99/C++11 only
void no type void n/a

This chapter is dedicated to exploring these basic data types in detail.

Defining a variable

In the “basic C++” section, you already learned how to define an integer variable:

To define variables of other data types, the idea is exactly the same:

In the following example, we define 5 different variables of 5 different types.

Note that void has special rules about how it can be used, so the following won’t work:

Variable initialization

When a variable is defined, you can immediately give that variable a value. This is called variable initialization (or initialization for short).

C++ supports two basic ways to initialize a variable. First, we can do copy initialization by using an equals sign:

Note that the equals sign here is just part of the syntax, and is not the same equals sign used to assign a value once the variable has been created.

Second, we can do a direct initialization by using parenthesis.

Even though direct initialization form looks a lot like a function call, the compiler keeps track of which names are variables and which are functions so that they can be resolved properly.

Direct initialization can perform better than copy initialization for some data types, and comes with some other benefits once we start talking about classes. It also helps differentiate initialization from assignment. Consequently, we recommend using direct initialization over copy initialization.

Rule: Favor direct initialization over copy initialization

Uniform initialization in C++11

Because C++ grew organically, the copy initialization and direct initialization forms only work for some types of variables (for example, you can’t use either of these forms to initialize a list of values).

In an attempt to provide a single initialization mechanism that will work with all data types, C++11 adds a new form of initialization called uniform initialization:

Initializing a variable with an empty brace indicates default initialization. Default initialization initializes the variable to zero (or empty, if that’s more appropriate for a given type).

Uniform initialization has the added benefit of disallowing “narrowing” type conversions. This means that if you try to use uniform initialization to initialize a variable with a value it can not safely hold, the compiler will throw an warning or error. For example:

Uniform initialization is sometimes called list initialization, though we prefer the term “uniform initialization” because neither the initializer nor the variable need to be a list.

Rule: If you’re using a C++11 compatible compiler, favor uniform initialization

Variable assignment

When a variable is given a value after it has been defined, it is called a copy assignment (or assignment for short).

C++ does not provide any built-in way to do a direct or uniform assignment.

Uninitialized variables

A variable that is not initialized is called an uninitialized variable. In C++, an uninitialized variable will have a garbage value until you assign a valid one. We discuss this in previous lesson A first look at variables, initialization, and assignment.

Rule: Always initialize your variables, or assign a value to them as soon as possible after defining them.

Defining multiple variables

It is possible to define multiple variables of the same type in a single statement by separating the names with a comma. The following 2 snippets of code are effectively the same:

You can also initialize multiple variables defined on the same line:

There are three mistakes that new programmers tend to make when defining multiple variables in the same statement.

The first mistake is giving each variable a type when defining variables in sequence. This is not a bad mistake because the compiler will complain and ask you to fix it.

The second error is to try to define variables of different types on the same line, which is not allowed. Variables of different types must be defined in separate statements. This is also not a bad mistake because the compiler will complain and ask you to fix it.

The last mistake is the dangerous case. In this case, the programmer mistakenly tries to initialize both variables by using one initialization statement:

In the top statement, variable “a” will be left uninitialized, and the compiler may or may not complain. If it doesn’t, this is a great way to have your program intermittently crash and produce sporadic results.

The best way to remember that this is wrong is to consider the case of direct initialization or uniform initialization:

This makes it seem a little more clear that the value 5 is only being assigned to variable b.

Because defining multiple variables on a single line AND initializing them is a recipe for mistakes, we recommend that you only define multiple variables on a line if you’re not initializing any of them.

Rule: Avoid defining multiple variables on a single line if initializing any of them.

Where to define variables

Older C compilers forced users to define all of the variables in a function at the top of the function:

This style is now obsolete. C++ compilers do not require all variables to be defined at the top of a function. The proper C++ style is to define variables as close to the first use of that variable as you reasonably can:

This has quite a few advantages.

First, variables that are defined only when needed are given context by the statements around them. If x were defined at the top of the function, we would have no idea what it was used for until we scanned the function and found where it was used. Defining x amongst a bunch of input/output statements helps make it obvious that this variable is being used for input and/or output.

Second, defining a variable only where it is needed tells us that this variable does not affect anything above it, making our program easier to understand and requiring less scrolling.

Finally, it reduces the likelihood of inadvertently leaving a variable uninitialized, because we can define and then immediately initialize it with the value we want it to have.

Most of the time, you’ll be able to declare a variable on the line immediately preceding the first use of that variable. However, you will occasionally encounter a case where this is either not desirable (due to performance reasons), or not possible (because the variable will get destroyed and you need it later). We’ll see examples of these cases in future chapters.

Rule: Define variables as close to their first use as you reasonably can.

2.2 -- Void
Index
1.12 -- Chapter 1 comprehensive quiz

110 comments to 2.1 — Fundamental variable definition, initialization, and assignment

  • Abhishek

    That was easy 😀

  • Jesse

    “This is not a bad mistake because the compiler will complain and ask you to fix it.”
    Shouldn’t this say:
    “This is a bad mistake because the compiler will complain and ask you to fix it.”

    • Nope. In my view, anything the compiler catches is not a bad mistake because the compiler points out exactly where the error is. Those tend to get fixed immediately. The bad mistakes are the ones the compiler doesn’t catch. Those are the ones that are likely to creep into production code (code released to the public).

  • Argon

    Hi, and thank you for a very informative and easy-to-read tutorial.

    One question to the “define variables along the way”.. I have a love for using this type of defining:

    type foo()
    {
    type tDescriptiveName(alternatively a default value); // Description
    type tDescriptiveName(alternatively a default value); // Description
    type tDescriptiveName(alternatively a default value); // Description
    type tDescriptiveName(alternatively a default value); // Description

    [… function code …]
    }

    Find this more tidy. And if var (witch it often is) are used more than once, “top description” will give a clear meaning.
    Any sense in this?

    • Well, if it’s your code you’re welcome to do whatever you like. 🙂 But generally, the declare your variables at the top style of declaration is considered deprecated in C++. My personal experience has taught me that it leads to tougher to read/understand code, even when they are commented.

      One issue with declare-at-the-top style of declaration is that you often have to scroll up to find out whether a variable is a local variable (declared in the function) or a function parameter. Declare-when-needed often doesn’t suffer from this wasted energy, since the majority of variables in a function will be declared when needed and used immediately thereafter.

      • Bradley

        Your second point, that you need to scroll up to find out whether a variable is a local variable or a function parameter is solved simply by following some common sense programming guidelines. Use prefixes on items to indicate what they are. For example;

        This method - or something like it - has been the standard at almost every company I have worked with in my 15+ years as a consultant. This notation, along with the use of meaningful variable names, makes most claims to one method of declaring variables being superior to the other pretty meaningless in my opinion.

        • Alex

          As noted in the lesson, declaring variables as close to the first use as possible is a widely accepted C++ convention. Whether you choose to follow convention is up to you.

          Companies that follow the “declare at the top” convention likely have roots in older C code, where that style of definition was a necessity, and haven’t updated their style guidelines in favor of modern best practices.

          I also would not recommend using the “pv” or “lv” prefix unless you like typing more than necessary. Variables should be assumed to be locally scoped unless otherwise indicated.

        • DR

          I wouldn’t go further than m_ when flagging variables in this day and age; Hungarian notation is a huge thing of the past and is discredited by Microsoft themselves.

          Why would you declare a variable that takes up memory if it might not be used…or if you leave it non-initialized what would be the use of "opening a back door" to something that could lead to a potential edge case bug.

  • CuView

    Does the ‘x’ variables above is initialized or not?
    How to know weather the variables is initialized or uninitialized?

    • When x is defined in your example, it is not intitialized. After the cin statement, x may or may not be initialized depending on whether the user entered a valid number or not. In this example, it would be a good idea to declare x and assign it to 0 immediately:

      There is no sure-fire way of telling whether a variable is initialized or not. Consequently, it’s a good idea to always initialize your variables when they are declared. That way, you won’t have to guess.

  • Ali

    what is the difference between the explicit assignment and the implicit assignment ? what does each one differ than another? where should I use them?

    • As far as I know, when it comes to built-in data types, there’s no substantive difference. I ran some timing tests on each and they performed identically in my test cases.
      For user-defined classes (something we’ll cover later), implicit initialization performs better, as it avoids making an unnecessary copy of the class.

  • Bob

    What is the fundamental difference between explicit and implicit assignment? Is there any reason to use one over the other? Is there any difference between ‘int nValue = 50’ and ‘int nValue(50)’? Does the compiler treat them differently? Or is the end result always the same regardless; nValue = 50.

  • Ben

    I used the following code:

    and it worked just fine, but the tutorial said it would not compile. Now I’m confused..

    • Actually if you read closely, I said it was dangerous, not that it wouldn’t compile. It WILL compile, but x will be uninitialized. Most new programmers assume that it will be initialized to 5, which is not the case. That’s why this is particularly dangerous.

  • Tate

    Would initializing the intiger x as it is taken from input work?
    e.g.

  • Hi, alex.
    can you tell me when I define an int like

    where is the information like the type and the address of i placed?

    • Alex

      Good question. The compiler creates something called a symbol table, to keep track of details like a variable’s name, type, scope, etc… The linker also has a symbol table to keep track of exported functions and variables so they can be properly linked. Symbol tables are complicated, and you probably won’t need to know the details of how they work unless you’re writing a parser or compiler.

  • Fluke

    Hi Alex,
    Great tutorial so far!

    A question about declaring variables where they are used.
    I am a bit old-style programmer and i cant find the arguments for declare variables when used to be so good.

    Here is my reasoning (proove me wrong, so i can change my style 🙂
    Lets see if we have 1000 lines of code. We have a function of 300 lines somewere inside (among other functions).
    If we use function variables more than once inside that function, and they are declared on their first use, isnt it harder, later on, to find out which one is global and which is declared within those 300 lines?
    Or just if we had all function variables just under function name - you can see on first glance which one is there and which one is global?

    • Alex

      I’d counter with a few points:
      1) Global variables should be used exceedingly rarely.
      2) If global variables are used, they can be easily identified if you label them with a specific prefix (e.g. g_).
      3) If your function is 300 lines, it probably should be refactored into smaller functions. I rarely write a function that is more than 100 lines, and most of the time they are less than 50.

  • Lilwolf

    I have a question…

    I’m learning Computer Science through a college class, and we were taught to declare variables in the header files under the private section with functions under public…

    Why? I’m a little confused and eager to learn, and sadly my professor doesn’t seem to be able to explain things too well. Help please!! 🙂

    • Alex

      When you say you were taught to declare variables “in the header files under the private section”, it sounds like you’re actually talking about how to write a class declaration. The rules for where class member variables and functions are defined are a little different (and covered in a future chapter).

      In this lesson, we’re talking about function parameters and local variables.

  • AsianBorat

    YES!!!! This is exactly what I was looking for! (I was wondering about the “int nValue1, nValue2 = 5; // wrong (nValue1 is uninitialized!)” bit when I was searching for an answer on google)

    I also learned a whole lot more about declaring ints than from other tutorials.

  • Shaun

    so then by making new functions such as:

    is kind of extra work if we can just declare the variables within the Main() function, and get the same output? for example:

    this doesnt require any other functions to add 2 numbers from a user and give a result. but in the chapter 1 comprehension quiz we needed 2 functions to do what this single Main() function can do without the hassle. am i missing something? or does this seem so much easier? or maybe that’s why you made this more clear in the next chapter? just want to note, i do understand making a function to do this for us is beneficial for multiple addition problems, but for a single one, i find this is much simpler.

    • rameye

      It was a quiz exercise on functions. Not a one-liner contest 🙂

      • Alex

        Yes, the chapter 1 comprehensive quiz has you go through extra steps for the purpose of ensuring you understand some basic concepts that will be used later. It’s a little extraneous, as you’ve noticed, but the understanding will serve you well in the future.

  • prafull.badyal

    gud..thanks to sir alex

  • Kostas81

    A quick question:

    Alex wrote: “The last mistake is the dangerous case. In this case, the programmer mistakenly tries to initialize both variables by using one assignment statement.

    1 int nValue1, nValue2 = 5; // wrong (nValue1 is uninitialized!)
    2
    3 int nValue1 = 5, nValue2 = 5; // correct

    In the top statement, the nValue1 variable will be left uninitialized, and the compiler will NOT complain. This is a great way to have your program intermittently crash and produce sporadic results.”

    But in section 1.3, “A first look at variables (and cin)” Alex had wrote:

    “A variable that has not been assigned a value is called an uninitialized variable. Uninitialized variables are very dangerous because they cause intermittent problems (due to having different values each time you run the program). This can make them very hard to debug. Most modern compilers WILL print warnings at compile-time if they can detect a variable that is used without being initialized.”

    And few lines before he wrote:

    “Some newer compilers, such as Visual Studio 2005 Express will pop up a debug error message if you run this program from within the IDE.” (He means a program with an uninitialized variable.)

    So, why here the compiler will not complain about the uninitialized variable???
    (And can someone tell me, “wrote” is the past tense for “write” or not? :D)

    • yes, ‘wrote’ is indeed the past tense for ‘write’.
      Anyway, I guess it depends on the compiler, because mine will pop up a warning in either case. I suppose VS05 did stuff differently.

      • Kostas81

        Thank you zingmars once again for your answer! (and for the little grammar help … 🙂 )

      • Alex

        I’ve found that Visual Studio is capable of showing uninitialized variable warnings for simple cases, but may or may not for slightly more complicated cases.

        For example, Visual Studio 2013 gives an unassigned variable compiler error for this code:

        But NOT for this code:

  • M Harran

    Alex, I’m coming late to the party but you should take pride that your tutorial is still proving useful to people 6 years down the road 🙂

    I’m coming from a C# background so I’m well used to the idea of employing something like

    Reading around places like stackoverflow, however, a lot of programmers say this is a bad idea, that you should specifically state the parts of the library that you are using i.e.

    Their argument is that by using the whole namespace, you may cause a conflict between a function in some other file that you are including which happens to have the same name as something in the standard library.

    Any comment on that argument?

    Thanks for a brilliant tutorial by the way, coming from C# and Visual Studio, it is perfect for me.

    • Alex

      Sure. The folks at Stack Overflow are correct -- the looser you are with your using statements, the more likely a naming conflict becomes. Explicitly including the classes you want from the library (e.g. using std::cin) is safer than including the whole library (using namespace std;). If you’re really concerned about naming conflicts, you can even go one step further and avoid “using” statements altogether and explicitly qualify everything. e.g.

      Generally, I’ve found that as long as your using statements are declared within functions (and not done at the global scope) the potential for conflicts is fairly minimal.

  • PrimalKyogreOVER9000!!!!

    Great tutorial Alex! Really enjoying so far.

    Can you please explain what bool, char, float and double variable types mean? And what are they used for?

    Thanks

  • Woopsie

    Third paragraph, second-to-last sentence, “it’s” should be “its”

    Also, last sentence before “Declaring a variable”, another it’s/its

  • Adam

    Alex,

    My background is in mechanical engineering. I've some experience with Python, MATLAB, and some Visual Basic in high school. I am telling you that as I believe my question stems from the experience I've had writing code for these applications as opposed to commercial software.

    In engineering and math it is often helpful to declare certain variables at the top. For instance a value for friction that is used in many equations and places throughout the code. The value can then be easily found and changed. This is not only easier but prevents mistakes by eliminating the need to find each use of the variable and change it locally.

    Is this a case where using an upfront declaration is appropriate? If not how would you handle a situation like this?

  • Chance Meser

    My code is saying:

    ‘main.exe’: Loaded ‘C:\Users\Chance\Documents\Visual Studio 2010\Projects\main\Debug\main.exe’, Symbols loaded.
    ‘main.exe’: Loaded ‘C:\Windows\SysWOW64\ntdll.dll’, Cannot find or open the PDB file
    ‘main.exe’: Loaded ‘C:\Windows\SysWOW64\kernel32.dll’, Cannot find or open the PDB file
    ‘main.exe’: Loaded ‘C:\Windows\SysWOW64\KernelBase.dll’, Cannot find or open the PDB file
    ‘main.exe’: Loaded ‘C:\Program Files (x86)\Norton 360\NortonData\21.6.0.32\Definitions\BASHDefs\20150309.001\UMEngx86.dll’, Cannot find or open the PDB file
    ‘main.exe’: Loaded ‘C:\Windows\SysWOW64\msvcp100d.dll’, Symbols loaded.
    ‘main.exe’: Loaded ‘C:\Windows\SysWOW64\msvcr100d.dll’, Symbols loaded.
    The thread ‘Win32 Thread’ (0xa24) has exited with code 0 (0x0).
    The program ‘[3856] main.exe: Native’ has exited with code 0 (0x0).

  • Win

    How does memory know what  type is stored there in memory. I mean how does it identify that this byte is type of int, and maybe another byte is type of char ,etc. Is there any value that tell the memory what type of this byte is.

    I’m sorry for my bad English. I hope you can understand what I mean.

    Thank you.

    • Alex

      Memory doesn’t know what type of data is stored in it. It’s just dumb storage.

      All variables have an associated address that gets assigned to the variable, either by the compiler at compile time or by the OS at runtime.

      The program also keeps a separate table of meta-information (called a symbol table) that includes things like the variable’s name, type, size, and scope.

      Between the address and the symbol table, the program has everything it needs to read/write values of a particular data type into memory.

  • Pankaj kushwaha

    Hi Alex ,
    you can also mention that :

    int i = 7.5 ;
    pass the compilation (with loss of data) , while
    int i(7.5)
    gives compilation error , so its safe to use second one.

  • Todd

    Typos.

    "The best way to remember that this is wrong is (to) consider the case of implicit initialization:"

    "Implicit initialization can also be more performant (can also perform better) in some cases." (oddly enough, ‘performant’ is a noun, not an adjective)

  • Avneet

    Alex, you can write about the safest way to initialize objects that is via the initializer list (I don’t know why the great stroustrup said it an initializer list while we can put in a single value). Compiler throws error when data lose is possible.

    int value {7.5} // compile error

  • Jim

    Alex,
    In this lesson I believe you introduced variable names with a prefix, like int nValue & bool bValue,for the first time.  But you failed to tell users why you used them. I believe this is a good programming practice and I think you should mention why.

    I’m wonder why you mentioned the following rule:

    "Rule: Use implicit initialization instead of explicit initialization"

    I’ve shown both below… I prefer the explicit because it’s easy to see that an assignment was made. Do you have a specific reason for this?

    One last thing you mentioned, "C++ does not provide any built-in way to do an implicit assignment."

    So you can implicit initialize int nValue(5). This does not make any sense to me, when in fact it has already been assigned (5)?

    • Alex

      Funny you should post this, as I was just in the process of revising the lesson. It’s updated now, have a re-read.

      1) Prefixing variables names with a letter indicating the type is called Hungarian Notation. This tutorial used to recommend it, but the best and brightest minds in the field have fairly unanimously concluded that it doesn’t provide enough value to be worthwhile, especially as compilers have gotten smarter and the language has gotten better (with C++11). I’ve been in the process of stripping it out of the tutorials as I rewrite them, but I missed a couple of instances here.

      2) Regarding implicit initialization, an assignment was NOT made -- an initialization was! The two seem similar (and achieve similar ends in this case) but are in fact distinct. It’s worth understanding the difference now, as it becomes more relevant later.

      The primary reason I recommend implicit over explicit initialization is that classes (which are a user-defined type that is at the heart of C++) cannot be initialized using explicit initialization. So you might as well get used to implicit initialization now, cause you’re going to have to use it a lot later.

      3) Again, make sure you understand the difference between initialization and assignment. You can implicitly initialize something, but C++ does not provide a way to implicitly assign a value (e.g. if you try value(5), it will think you’re trying to make a function call, not do an implicit assignment).

  • List initialization is the safest way to initialize a variable. It gives a warning when narrowing conversion occurs in Code::Blocks (C++ 11) and throws an error in updated(or other) compilers/IDE’s.

    All the readers can have a look at this Online Compiled Code

  • Thomas Keith

    I have run into some coders that have declared their variables at the top of their (.vbs) code.  I always found it difficult to troubleshoot the script when it was necessary.  Does anyone know why the "declare at top" protocol was initiated in the first place?  I totally agree with "declare & initialize when used."  That’s my M.O.

    • Alex

      Some (mostly older) languages used to require all variables to be declared at the top of the file or function. C used to be like this until C99.

      Modern best practices are to declare variables as close to their first use as possible. However, some older programmers have habits that die hard.

  • yash

    I am using visual studio 2012….
    Can I use c++11 feature in it?
    When I use use uniform initialization it gives me error…….
    Please give me it’s solution
    And thanks for making this tutorials.

  • Sarhad Salam

    If I use uniform initialization, and my compiler supports it. Can I run my app in older computers?. If I follow C++11 rules, will old computers support it? (Say windows xp, or ubuntu 9, or any such)

    Thanks.

    • Alex

      Yes, once your app is compiled into an executable for a certain architecture, the compiler and which set of C++ features you used in our program doesn’t matter.

  • Aimee

    Hi Alex,

    Great tutorials so far but I’m not still not sure if I understand the difference in usage between brackets ‘ () ‘ and squiggly brackets ‘ {} ‘ during initialization of the variables.

    From what I understand, both bracket types seem to be appropriate for the initialization of variables so long as the variable introduced belongs to that class (ie, int nValue(4) is not different from int nValue{4}, but int nValue{4.5} does not work since 4.5 isn’t an integer), and brackets do not work for lists.

    Is this true? Are there any other differences between the two bracket types?

    Thanks 🙂

    • Alex

      Both types are appropriate for initializing variables. The “squiggly” braces {} should be preferred if you’re using a C++11 compatible compiler because they work for all kinds of initialization, whereas the parenthesis braces () work for initializing most (but not all) types. As you correctly note, the squiggly braces also prevent most implicit type conversions, which is generally a good thing.

      • Nick L

        I’m using Visual Studio Community 2015. Should I only use the {} initialization in the future of these tutorials? Also, after the initialization, should I go about as usual and use the = for assignment? so:

        and just ignore the () and = initialization altogether?

  • Javad

    Hi Alex,

    I believe it is not accurate to say "Uniform initialization disallows type conversion" as indicated in the lesson under Uniform initialization in C++11. Uniform initialization disallows type conversion if it involves narrowing. However, if type conversion can be performed without narrowing it is allowed. For example the following code compiles fine:

    char c{ ‘c’ };
    int i{ c };
    bool b{ true };
    int x{ b };
    char z{ 20 };

  • Lokesh

    Hi Alex,
    I am using -std=c++11 option to compile the following program with g++ along with some other options(-Wall -pedantic) and instead of giving me an error, it just gives me a warning.

    warning: narrowing conversion of ‘5.5999999999999996e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
    int nValue3{5.6}; // Universal initialization.

    The program compiles and runs with the following output:
    1
    2
    5

    Am I missing something?

    • Alex

      Apparently the compiler is not required to generate an error for a narrowing conversion -- just some kind of diagnostic message. Older versions of GCC gave an error, but they changed it to a warning in newer versions to increase compatibility with older code bases.

  • Heitor

    Hi, in a long and complex program it won’t be an hassle to find where it is the declarations of the variables? I have the habit to declare them at the top of the function like in the old C compilers or declare variables in a seperate file, so I can find easily where the declaration of the variables are. Is this a bad way to do it? Just a question that may increase my performance I guess :/

    By the way I am enjoying to read your lessons, you teach very well. More than my old teacher (where she teached me how to use Visual Basic). I like to learn all about the language, not half. You deserve my congratz 😀

    • Alex

      Modern IDEs should show you the variable declarations on hover, so there’s no need to scroll to find them. Also if you generally declare variables as close to the first use as possible, the declarations are right above the code that uses them.

      Keeping your functions short and modular also helps.

  • Chuck

    In the code snippet

    The line

    Is missing a semicolon. Not sure if it was a typo or not.

  • Nyap

    will you update the website when C++17 comes out?
    edit: and btw, why are explicit and implicit initializations called that? is it because explicit is a bit more obvious because of the assignment operator?

    • Alex

      If I’m still around, I will update for C++17.

      I’ve updated the names of the initialization forms to be more in line with accepted standards. Explicit initialization is more commonly called copy initialization, and implicit initialization is more commonly called direct initialization.

      • Nyap

        will you get a guy to replace you when you leave? bc i’ve been making really bad progress because of school, so I might need to hurry up if you’re just going to leave the site without someone at least replying to the comments

  • Rafal

    Can you explain me benefits of using direct initialization of variables ? What’s the difference between direct and copy ? I understand them when we are using classes but what about int, float etc?

  • Chris

    The following code compiled and ran without a problem before I added the third to last statement, the one that is supposed to list initialize value to 4. The compiler complains that a ; needs to be put at the end of this statement.  

    Why does the compiler not recognize this mode of initialization?

    The version of C++ I am using includes cstdint, so I assume I am using C++11

    I am currently using the Eclipse IDE on my mac if that helps.

  • Chris

    The line in question (line 30) has a semicolon.

    • Alex

      You’re saying the compiler is complaining about line 30 needing a semicolon even though you already have one? It sounds like your compiler either isn’t C++11 compatible, or maybe that functionality is not turned on. You may need to add compiler option -std=c++11 to your compiler settings. See this page for more info.

  • de.rock

    When i Initializing a variable with empty parenthesis i.e int x()  output is 1 and
    Initializing same variable with nothing i.e int x  output is 4291710. Can any please explain why different output for same variable…tnx..

  • Raquib

    I am confused by a portion (copied below) explained in this tutorial---

    ---------------------------------------------------------------------
    The last mistake is the dangerous case. In this case, the programmer mistakenly tries to initialize both variables by using one assignment statement:

    int a, b = 5; // wrong (a is uninitialized!)

    int a= 5, b= 5; // correct
    -----------------------------------------------------------------------

    My question is why is this called to be an assignment statement ?? I thought, the ‘=’ sign here was just a part of syntax for copy initialization and should not be confused with assignment ‘=’.

    Am I missing something ??

    • Alex

      No, you are correct. I’ve updated the tutorial to use “initialization” instead of “assignment”, as it should be.

      • Raquib

        Thanks for your prompt reply. Awesome tutorial BTW. I have already sent a mail expressing how awesome it is so will avoid it here. Thanks a lot.

  • Dragos

    Now when u left a variable uninitialized, isn’t it automatically initialized with 0?

  • Hi Alex,
    I have one doubt related to address concept

    Consider my compiler architecture is 32 bit(4 byte) and size of short is 16 bit and char is 8 bit
    If I have a structure with structure packing is enabled(No padding)
    like

    here both the members are stored in the same address, is it right ?

    then if I read the variable s_var2 like obj.s_var2. variable read the particular memory, so in this case both the member variable have same memory. In this case how we get the correct value of s_var2? or it is impossible ?

    • Alex

      No, if there’s no padding then s_var1 will be stored in the first 8 bytes, and s_var2 will be stored in the next 16 bytes.

      You can prove this yourself by implementing the above, and printing the address of obj.s_var1 and obj.s_var2.

      • Hi Alex,
        Thanks for the replay

        How can I check with structure packing in a compiler, is any configuration in compiler. May be am wrong, My idea about address is, a 32 bit architecture can hold 32 bit data in a single address.
        ie, consider 0x0FFE1 is my address and it have 32 bit, and both the members are stored in the single address 0x00FFE1 is it correct?

        • Alex

          Compilers should have an option to set data structure alignment.

          A 32-bit architecture does not hold 32-bits of data in a single address. Most architectures are byte-addressable, which means that one address holds 1 byte of data. A 32-bit architecture means that the CPU can process 32-bits of data at once (4 addresses worth), as well as address 32-bits of memory addresses (4GB).

          In the future, please try and leave comments on the lessons more appropriate to the topic you’re asking about. This topic is really better discussed in the lesson 4.7 -- Structs.

  • Nick

    Correct me if I’m wrong, but under "Defining a variable" the example of all 5 variable types does not include void, but does include both float and double, which are the same thing, and is thus an incorrect example of all 5 variable types?

    • Alex

      The example isn’t intended to be an example of how to declare all 5 types, least of all because you can’t declare a variable of type void. I’ve added a note to the lesson about that.

  • George

    I’m not too sure I understand with regards to the defining/initialization. Is what you’re saying that you can define a variable separately but with initialization you can define and give it a value on one line? And with the assignment is that simply when you want to give it a value at a lower line so you define it and don’t initialize? I’ve read it a couple times but I’m still not sure.

    Also:
    "When a variable is given a value after it has been defined, it is called ""an"" copy assignment (or assignment for short)."

    • Alex

      When a variable is defined, memory is allocated for it. We can define a variable with no initial value:

      But this is generally bad practice, because x will be given a garbage value, and that’s usually not desirable. So when we define a variable, we can initialize it, which simply means that we’re providing it with an initial value:

      A variable can only be initialized at the point of definition.

      Later on, if we want to _change_ the value that a variable has, we can assign a new value to it, via the assignment operator (=). You can do this regardless of whether the variable was initialized or not.

      Make sense? Also, typo fixed. Thanks!

  • Nguyen

    Hi Alex,

    "To recap briefly, computers have random access memory (RAM) that is available for programs to use. When a variable is defined, a piece of that memory is set aside for that variable."

    When I read about the Memory addresses, I start getting confused.  Here are what I guess "When a variable is defined, a memory address is set aside for that variable"

    I don’t know if a variable has anything to do with the memory address when a variable is defined?

    Thank you

    • Alex

      Let’s recap:
      1) Your computer has memory.
      2) Memory is used to store values.
      3) Each byte of memory has a unique address.
      4) Memory addresses are hard to work with (because they are just numbers).

      So, when you declare a variable, you’re doing a few things:
      A) You’re telling the compiler to reserve some memory for you.
      B) You’re telling the compiler how to convert the contents of that memory into a specific type of value.
      C) You’re telling the compiler what you want to call that memory.

      For example, when you say

      You’re telling the compiler that you want to reserve 4 bytes of memory, that the value should be interpreted as an integer, and that you want to name that memory location “x”.

Leave a Comment

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