Variable Initialization in C++
The keyword auto asks the compiler to determine a variable's type instead of the programmer writing the type name.
A Declaration Needs a Value
A variable declaration can look finished even when the variable has not been given a value. That gap matters: a program should not depend on a value that was never chosen. C++ also provides auto, which asks the compiler to determine a variable's type. Following how the compiler makes that choice reveals why an initializer is central to both type deduction and good initialization practice.
What an Uninitialized Declaration Leaves Open
What do you think happens?
A variable has been declared, but no value has been chosen for it yet. Is it ready for your program to rely on?
Reveal answer
No. A declared variable without an initialized value is not ready to be relied on.
A declaration names a variable, but initialization gives it the value it will hold. The safe practice is not to depend on a value that was never chosen.
Initialization gives a variable the value it will hold. Until a value has been chosen, do not write later code that depends on that variable containing a meaningful value. A declaration followed by a plan to fill in the value later leaves a window in which the variable exists but is not ready to use.
How auto Gets Its Type
Type deduction is the process of asking the compiler to work out a variable's type instead of writing the type name yourself. In C++, auto requests this deduction. It does not mean the variable has no type: the compiler determines a type from the initializer.
The initializer is the expression that gives the variable its initial value. For an auto declaration, it is also the source of information about the type. The compiler does not infer the type from the variable's name or wait to see what later lines do. It reads the initializer, which may be a literal or a fuller expression, and settles the type at the declaration.
Deduce a Type from an Expression
Suppose count has type int. What type does auto deduce for total in this declaration?
- 1Read the initializer
The initializer is count + 8, not the name total.
- 2Use the expression's type
The expression count + 8 produces an int.
- 3Apply deduction
The compiler uses the initializer's type for total.
total is deduced to have type int.
- The initializer is count + 8.
- If count has type int, this expression produces int, so total is deduced as int.
Why auto Requires an Initializer
What do you think happens?
If you write auto x; without an initializer, what information can the compiler use to deduce x's type?
Reveal answer
There is no initializer to provide the type.
An auto declaration asks the compiler to determine a type from the initializer. Without one, the compiler has nothing to read for that deduction.
Declare When the Value Is Ready
Do not declare a variable before you have a value to initialize it with. Where possible, declare and initialize together, close to where the value is computed or known. This avoids leaving a variable in a half-finished state between its declaration and its first meaningful value.
- The declaration and initial value are together.
computed_valuestands for a value available at this point in the program.
Keep Each Variable's Scope Small
A variable's scope is the part of the code in which that variable can be used. Keeping scope as small as necessary means declaring the variable in the narrowest region that still lets it do its job.
A function body can contain a loop body, and a loop body can contain an if block. A variable declared in the innermost block is available only in that region. Choose the narrowest region that still lets the variable do its job: this limits the places where it can be misused or accidentally changed.
Mistakes That Leave Variables Unready
Common mistake Assuming a declaration alone makes a variable ready to use.
What it looks likeint result;Why it failsThe declaration has not given result a value. Code that depends on a value that was never chosen is not a sound practice.
Do this insteadInitialize result when a value is ready, preferably in the declaration.
Common mistake Writing auto without an initializer.
What it looks likeauto item;
Why it failsThere is no initializer for the compiler to use when determining the type.
Do this insteadProvide an initializer in the auto declaration.
Common mistake Declaring a variable long before its value is ready.
What it looks likeDeclare a variable first, then assign its value later.
Why it failsThis creates a period in which the variable exists without a meaningful value.
Do this insteadDeclare it near the point where its value is known and initialize it there.
Common mistake Making a variable visible in a wider region than it needs.
Why it failsA wider scope creates more places where the variable can be misused or accidentally changed.
Do this insteadDeclare it in the narrowest region that still lets it do its job.
Check Your Understanding
Assume count has type int. What type does auto deduce for total? Then explain why the declaration needs the expression on its right-hand side.
Hints
- Look at the initializer, not the variable name.
- The expression count + 8 produces an int.
A variable is declared near the start of a function, but it is only needed inside one nested block and receives its value later. Name two changes that would make this pattern better.
Hints
- Consider when a variable should be declared.
- Consider how much of the code needs to be able to use it.
A Reliable Declaration Habit
For auto, follow the initializer to find the type: the compiler reads that expression and deduces the variable's type from it. For safer variable use, initialize a variable before relying on its value, declare it when the value is ready, and keep it visible only in the region where it is needed.
Key Takeaways
- auto asks the compiler to determine a variable's type; it does not leave the variable without a type.
- The initializer is the source of type information for an auto declaration.
- An auto declaration without an initializer has no information from which to deduce a type.
- Initialize a variable before relying on its value, and declare it when that value is ready.
- Keep a variable's scope as small as necessary to limit where it can be misused or accidentally changed.