Type Conversions in Arithmetic
Auto lets the compiler deduce a variable's type from its initializer, so the form is auto variable_name = initializer;.
Declaring a Variable Without Naming Its Type
Most variable definitions you have seen so far name the type before the variable, as in double price = 2.5;. The type name tells the reader what kind of value the variable will hold. Auto offers a different route: you leave the type out and let the value on the right-hand side decide it. The equals sign still does its normal job, which is giving the variable its starting value.
What do you think happens?
In the declaration auto x = 123;, what type does x end up with?
Reveal answer
int
A whole number such as 123 is an int, and auto gives x the type of its initializer, so x is an int. Nothing about the name x or the word auto chooses the type.
Reading the Right-Hand Side First
The rule is simple to apply once you look at the right-hand side first. Whatever kind of value the initializer produces is the kind of value the variable will be. The type of a variable declared with auto is therefore a consequence of the expression you write after the equals sign, not a choice you make on the left.
| Initializer | Kind of value | Type auto gives the variable |
|---|---|---|
| true | a literal truth value | bool |
| 'A' | a character in single quotes | char |
| 123 | a whole number | int |
| 1.2 | a number with a decimal point | double |
| sqrt(y) | the return value of a function call | the return type of sqrt |
Each initializer determines the variable's type. The function call row shows that the initializer does not have to be a literal.
- flag takes the type bool from the literal true
- letter takes the type char from the character literal 'A'
- count takes the type int from the whole number 123
- price takes the type double from the decimal literal 1.2
The function-call row deserves a closer look. Suppose a variable z is declared with auto and its initializer is sqrt(y). The variable z does not get a type because of anything you typed next to z. Its type is whatever sqrt(y) returns, and the compiler copies that type onto z. Auto makes this link explicit: the function call is the source of the information. The same idea applies to any expression, so auto is not limited to literal values.
Tracing Where the Type Comes From
When the compiler meets an auto declaration, the path it follows is short. It starts from the initializer expression, determines the kind of value that expression produces, and gives the variable that same type. The variable then holds the value in a variable of exactly that type. The diagram traces this path for a declaration of the form auto variable_name = initializer;.
Anatomy of the auto Declaration
Each part of an auto declaration has a distinct job. The keyword auto marks the declaration as one whose type will be deduced. The variable_name is the name you choose. The equals sign gives the variable its starting value. The initializer on the right is the part that determines the type.
Why auto Avoids a Conversion at the Declaration
Conversions are where surprises usually come from. When the type written on the left does not match the type of the value on the right, the value may be changed to fit, and that change may lose information. An explicit type can create this mismatch if you choose a type different from the one the initializer produces.
- The explicit int forces the value 2.5 to be changed to fit an int, which can lose information
- auto copies the type of 2.5, so no mismatch exists at the declaration
The source describes the key idea precisely: auto does not change the type of the value. The variable's type is the type of the initializer, so the value is stored in a variable of exactly that type. Because auto copies the type from the value, that mismatch cannot occur at the point of the declaration. This is the sense in which auto avoids a conversion at the start of the variable's life.
Choosing auto or an Explicit Type
The default approach is to use auto when you have no specific reason to mention the type. Auto is the everyday choice, and an explicit type is the exception that needs a justification. The source names two kinds of justification. An explicit type is worth writing when the declaration is in a large scope, or when exact range or precision matters.
Auto also helps with redundancy and long type names. The source notes that this is especially important in generic programming, where the exact type of an object can be hard for the programmer to know and the type names can be quite long. In that setting, auto lets you define the variable without first working out and typing the full name.
| Situation | Prefer auto | Prefer an explicit type |
|---|---|---|
| No specific reason to mention the type | Yes, this is the default | Not needed |
| Long or hard-to-know type names, as in generic code | Yes, avoids writing the full name | Only if the name is needed for clarity |
| Declaration in a large scope | Less preferred | Yes, the source names this as a justification |
| Exact range or precision matters | Less preferred | Yes, the source names this as a justification |
Auto is the everyday choice. An explicit type needs a reason such as scope, range, or precision.
Mistakes With Hidden Types
Common mistake Assuming auto picks a type from the name of the variable
What it looks likeauto total = 2.5;Why it failsThe type comes from the initializer on the right, not from the name total or from what the variable seems to hold.
Do this insteadLook at the right-hand side. Here 2.5 has a decimal point, so total takes the type double.
Common mistake Writing an explicit type that does not match the value and expecting no change
What it looks likeint n = 2.5;Why it failsWhen the left-hand type does not match the value on the right, the value may be changed to fit and information may be lost.
Do this insteadUse auto so the type follows the value, or choose an explicit type that matches the value deliberately.
Common mistake Using auto everywhere without considering the reader
Why it failsIn a large scope or where exact range or precision matters, the type is information the reader needs to see.
Do this insteadKeep auto as the default, but write the explicit type when the scope or precision makes it important.
Tracing Declarations by Hand
For each declaration, state the type the variable receives. Look only at the right-hand side: auto x = true; auto y = 'B'; auto z = 10; auto w = 0.75;
Hints
- Match each initializer to its kind: true is bool, a character in single quotes is char, a whole number is int, a decimal number is double.
- Do not look at the variable name to decide the type.
A colleague writes auto ratio = sqrt(area); in a large function. Explain what determines the type of ratio, and state whether you would keep auto or write an explicit type, giving one reason.
Hints
- The type of ratio is whatever sqrt(area) returns.
- Consider the two justifications for an explicit type: large scope, and exact range or precision.
Key Takeaways
- auto lets the compiler deduce a variable's type from its initializer, using the form auto
variable_name= initializer;. - The kind of value on the right-hand side determines the type: true gives bool, 'A' gives char, 123 gives int, and 1.2 gives double.
- Because auto copies the type of the initializer, the declaration itself avoids the conversion that happens when an explicit type does not match the value.
- Use auto by default, and write an explicit type when the declaration is in a large scope or when exact range or precision matters.