# 2.1 — Fundamental variable definition, initialization, and assignment

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 memory addresses (or addresses for short). 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 known as a byte. The modern standard is that a byte is comprised of 8 sequential bits. Note that some older or non-standard machines may have bytes of a different size -- however, we generally need not worry about these. For these tutorials, we’ll assume a byte is 8 bits.

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

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 non-fractional 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 introduced in C++11
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 introduced in C99/C++11
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 three basic ways to initialize a variable. First, we can do copy initialization by using an equals sign:

(Note for advanced users: The equals sign used here for copy initialization is part of the initialization syntax, and is not considered a use of the assignment operator that gets invoked when doing copy assignment)

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 (also called brace 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:

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++, a fundamental variable that is uninitialized 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.

Side note: C++ also has other non-fundamental types, such as pointers, structs, and classes. Some of these do not initialize by default, and some of them do. We’ll explore these types in future lessons. For now, it’s safer to assume all types do not initialize by default.

Rule: Always initialize your fundamental 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

### 190 comments to 2.1 — Fundamental variable definition, initialization, and assignment

• prince

Hi Alex,
i wrote
int value{7.5};
and it printed as 7 as expected but without warning or errors in codeblock contradicted to
but you said it disallows narrowing type conversions and above code-line should  produce  an error.

2.
one more doubt sir
"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."

in above line i am not able to make out what is the difference plz explain it elaboratly.

• Alex

1) Your compiler should be giving you a narrowing conversion error. If it isn't, it's either doing something incorrectly, or you have some parameter enabled that is telling your compiler to ignore this error.

2) When you have a statement like int x = 5, the = sign is part of the syntax of the statement used to separate the variable name for the initialization. This differs from a statement like x = 5, where = is an operator that calls a function. It's not super important at this point, but becomes more meaningful in chapter 9 when we cover operator overloading.

• James Smith

• Muru

My dear teacher,

Thank you so much for these tutorials. I had been banging my head against wall to learn C++. You made it accessible for me with your tips and clear examples.

Thank you.

Regards,
muru

• Zero Cool

Hey Alex. How are you doing?
I think you should update the table of fundamental types to say that some types like char16_t or char32_t are C++14 standard too.

Once again thanks for the great website you have made.

• Alex

char16_t and char32_t are part of the C++11 standard, not the C++14 standard. Compilers that are C++11 compliant or newer (including compilers that are C++14 compliant) should be able to use these.

• Zero Cool

Thanks Alex for your reply. I realise now that i did a very stupid suggestion.

Once more thanks for this amazing site.

• Xenel

I was wondering what the best choice is for initialization of variables. There was another comment saying that list (uniform) initialization was the safest because of conversion but I was wondering what the actual best practice in the real world was as opposed to it simply being safer.

I've read through a bit more of the chapters and I mostly only see direct initializations used but my understanding was that uniform initializations are the best choice if using at least C++11 and variable conversion isn't planned.

• Alex

Uniform initialization is best in the real world. It's the safest and most consistent option, and it doesn't add additional burden.

Many of these tutorials do copy or direct initialization because they were written pre-C++11 and then adapted. Ideally they should be updated but I've been focused on other things like answering comments. 🙂

• Xenel

Thanks for the reply. It's greatly appreciated. I don't mind that it isn't up to date in this constantly changing world. As long as my question is answered, the majority of these tutorials still give me that basic gist of things. Eventually I could have probably figured that out but I'd like to apply the best practice as soon as possible if I can.

Thanks again.

• gary wang

Hi, thanks for the great tutorial. May I ask what do you mean by "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." Can you give an example? thanks so much

• Alex

Although these two lines look similar (both use an equals sign) and perform similar functions, C++ treats them differently. The equals signs are not related. In the top line, the equals sign is part of the copy initialization syntax. In the bottom line, the equals sign is the assignment operator, which is evaluated the same way other operators are.

It doesn't make a huge amount of difference at this point, but later on we'll see that we can override the assignment operator -- this doesn't have any impact on copy initialization, since it doesn't use the assignment operator.

• gary wang

Oh, I see. I always thought they are the same thing.
So basically, the both equal sign(=) are the same sign but they mean the different thing, just like * operator, one is for the pointer and other is for multiplication.
Thanks so much for the explanation!

• Alex

Exactly! C++ is full of things like this, where symbols are reused but have different meanings in different contexts. & is another one: in some contexts it's the address-of operator. In other contexts it means reference.

• Rob

Can I trust the computer to "leave" my variable at the same address or will the OS move it around if it needs to (assuming the variable not getting destroyed in the meantime). Eg. could I get the address of the variable and just refer to it by address, not name? I understand that this might be dangerous, and probably not useful in most situations, so it's mostly just curiosity.

Secondly, can I ask for specific memory addresses for my variable (or maybe just for consecutive ones). Could there be a performance benefit or is reading four addresses at random just as fast as reading four consecutive ones?

• Alex

1) Once a variable has been given a memory address, the OS won't randomly change it -- but only so long as that variable is still in scope. Once that variable is destroyed, the program may reuse that memory address for something else.

Variables may have different address with each execution of the program, and function parameters may be given different addresses each time the function is called.

So yes, you can refer to a variable by address if you want. And yes, this is dangerous because the variable may go out of scope and get destroyed, you may end up referencing a memory location that's been reused for something else.

2) No, you can't ask for a specific memory address. There may be some a performance benefit from having data that's accessed together be close in memory together (due to caching), but in most cases we tend to get that for free anyway via using arrays and classes, both of which allow us to aggregate related data into sequential memory.

• Theo

Dear Teacher ,
can you please better explain whats the diference between (assigning an value to an integer)
and (initializing it)

• Alex

Initialization occurs when you provide an initial value to a variable at the point where it is defined. Assignment happens when you provide a new value to a variable after it is defined.

In most cases, the end result is the same. However, later on, we'll start seeing some cases where variables must be initialized, or can not be assigned to. So it's worth understanding the distinction now, even though in both cases (when it is allowed) the variable acquires the value.

• Theo

Dear Teacher ,
So is there a point in assigning a value to a void function, knowing that it wont return that value to main func.?

• Alex

I'm not sure what you mean by "assigning a value to a void function". Are you talking about return values? It's a syntax error for a function that returns void to try to return a value back to the caller.

• Theo

Dear teacher ,
sorry for poor imprecise language , u got it right.

• Stan

Just wanted to comment and say this whole tutorial has been very interesting and helpful, thank you!

• B1

hi there Alex sorry for bothering you
but i wrote a small code on Online Compiler (codechef.com)
and it gave me an error
i tried the code with (NetBeans) it also gave me the same error

when i do this

it gives me this error "prog.cpp:9:1: error: 'g1' does not name a type"

but when i do this

it compiles fine...is assigning forbidden in the global scope or what ?

• Alex

Yes. You can define things in the global scope, but you can not execute code in the global scope. So the definition of g1 is okay, but the assignment is not.

If you want to do this, you should define g1 with an initializer (int g1 = 44;).

• B1

oh..right
execution of the code will begin & end in main()
my thick head missed this info

thank you Alex

• Jim Smith

But this is new information. In the global scope C++ allows some statements like definitions (int x;) and forbids other statements like assignments (x = 2;). Shouldn't this be included in the tutorial?

• Alex

Probably, but we haven't even covered the global scope at this point in the tutorial, so it might be a bit premature to do so before or at this point..

• dgo

[code]
#include <iostream>

int main()
{
int x{3};
std::cout << "x is initialized as " << x << std::endl;
}

Seems like uniform initialization doesn't work..
It does not compile and complains that
[code]
variable1.cpp:5:10: error: expected ';' at end of declaration
int x{3};

A version of the compiler is the following:

Dongwooks-MacBook-Pro:ch2 dgo\$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.3.0
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

• Alex

Your compiler probably isn't C++11 compliant. You'll either need to pass it a flag telling it to use C++11 compatibility mode, or upgrade to a newer compiler that supports C++11.

• dgo

Then I should install a new version of compiler!

• Georges Theodosiou

My dear c++ Teacher,
Please let me say, it is not that every compiler will throw an warning or error if I try to use uniform initialization to initialize a variable with a value it can not safely hold. For your example

https://www.codechef.com/ide >> 4.
http://cpp.sh/ >> nothing.
http://rextester.com/l/cpp_online_compiler_gcc >> 4.
https://www.tutorialspoint.com/cplusplus/index.htm >>
main.cpp: In function ‘int main()’:
main.cpp:5:18: warning: narrowing conversion of ‘4.5e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
int value{4.5};
^
So of the 4 compilers online only one throw an warning.
With regards and friendship.

• Alex

cpp.sh gives a warning, you can see the yellow triangle symbol at the line of code, and if you click on the "compilation" tab you'll see the warning.

But you're right, some of the others don't appear to be compliant with the C++ specification in this regard. Note that narrowing conversions in a uniform initialization should be an error, not a warning!

• McSteven

But the value will be truncated if it's an decimal value, not so?

• Alex

With copy or direct initialization, yes. With uniform initialization, doing a narrowing conversion should be an error.

• 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:
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".

• 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!

• George

Thank you! <3 I get it now

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

• McSteven

Can you enlighten me, I don't understand the difference between float and double types.

• Alex

Float and double serve the same purpose (much like a short, int, and long do), but have different ranges and precisions. We talk more about all of these in upcoming lessons in this chapter.

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

• Dragos

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

• Alex

No, it's not. Uninitialized variables in C++ will have junk values, based on whatever data already happened to be in the memory address that the variable was given.

• Dragos

Thanks. Keep up the good work!

• McSteven

if it is uninitialized in the global scope, yes the variable is initialized to 0.

• Alex

Only for global or static variables -- but better to not rely on this and always give your fundamental variables explicit, known values.

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

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

• Alex

int x(); isn't an empty variable initialization, it's a function prototype. Unless you happened to have a function named x with the same prototype, this shouldn't have even linked.

• de.rock

isn't t this is also called empty variable direct initialization... int x(); ...

• Alex

No. C++ doesn't support direct initialization of fundamental variables with an empty parameter list.

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

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

• Alex

Variable definitions are statements (whether they contain initializations or not), and statements end in a semicolon in C++.

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

• Alex

With fundamental variables, there's essentially no difference between direct initialization and copy initialization.

• Sihoo

thanks.

• 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

• Alex

I'm not planning on leaving anytime soon.

• Chuck

In the code snippet

The line

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

• Alex

Yup, typo. Fixed. Thanks!

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

• Peter Baum

I'm with Heitor on this one.  While there are advantages for each method, I would point out that:

1. It is neater to have the declarations in one place; an unnecessary clutter if placed next to its first use.  During debug, one will mostly not be concerned with the declaration.

2. If checking the declarations during debug, it is handy to have them all in one place so you can easily compare the types of related variables.  That is awkward if hovering.

3. The use of a variable may take place in several separate sections of code, so an explanation of a variable's use (as a comment) is sometimes more appropriate in one expected location before all these sections.

4. By placing the declarations at the top, we don't have to have a special rule for things like globals.

But overall, this tutorial is terrific and I'm learning a great deal.

• Alex

You're certainly welcome to do whatever you like -- however, I would point out declaring your variables in as small a scope as possible, and as close to the first use as possible, is a well established best practice in the industry. There is very little debate on this point.

• Peter Baum

Hi Alex,

Thanks so much for taking the time to reply.

Perhaps it would be helpful to separate the issue of declaring variables in as small a scope as possible from the issue of declaring variables “as late as possible.”  I don’t think there is any disagreement about the former.

I hope we have more justification for whatever approach we take than an appeal to authority.

I can think of one situation where we might wish to declare variables later rather than at the top of a block.  Depending upon the compiler, some objects may require function calls for their creation, and we might therefore want to invoke those expensive calls at run time only if the objects were actually needed.  The last lesson on timing code might be helpful here.

Regards,
Peter

• Alex

There's really no disagreement about either point.

Whether instantiating those variables is expensive or not, defining your variables at the top of a block increases complexity by removing context about what the variable is used for. When you declare everything at the top of the function, you're dumping a pile of non-contextual information on the reader, forcing them to look through your code to see what's used where and how.

One other good reason to declare as close to first use as possible: constants must be initialized on definition. You may not know what the initialization value is until later in the function.

Also see: http://wiki.c2.com/?DeclareVariablesAtFirstUse

• Peter Baum

Regarding “…defining your variables at the top of a block increases complexity by removing context about what the variable is used for.” – You are correct that some code does this, but it is very common to find code where the purpose is distributed among several sections of code and its first use does not fully illuminate this context.

Regarding “You may not know what the initialization value is until later in the function.” – Of course, but frequently this is not the case.

Thanks for the link to http://wiki.c2.com/?DeclareVariablesAtFirstUse.  I didn’t see anything new there but it did remind me that both sides of this issue have their champions and favorite examples.  Habit and familiarity also play a role.

I’ll just leave it at that unless someone can come up with some new pro or con.

(And finally… again, thank you Alex for the hard work you put into this site.  It is much appreciated.)

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

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 };

• Alex

Thanks for the correction. I've updated the article as appropriate.

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

• Alex

Yeah, if you have a C++11 compatible compiler (like Visual Studio 2015), I'd recommend using {} for initialization and = for assignment.

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.

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