Bitesize Modern C++ : auto

C++ is a statically-typed language, that is, you must explicitly declare the type of every object before use. The type of an object specifies

  • The amount of memory occupied
  • How the memory (bits) is interpreted
  • The operations allowable on the object

An object’s type is fixed at declaration – unless the programmer chooses to circumvent the type system using a cast.

Often for C++ objects specifying the type can be onerous:

image

C++11 allows automatic type-deduction to simplify the creation and maintenance of code.

The auto keyword has been appropriated from C (where it was a storage specifier indicating a local – ‘automatic’ – variable) that is almost never used.  From C++11 onwards auto now means ‘deduce the type of an object’

Let’s start with some simple (but not particularly useful) examples.

image

The compiler uses the type of the initialiser to establish the type of the new object. Note, the object still has a definitive (and fixed) type. Type-deduction does not lead to ‘duck typing’.

(As an aside, one might reasonably argue that there is very little benefit in auto-deducing built-in types; and, in fact, could even be less explicit to the reader)

To use auto the compiler must have the information to deduce the type (and therefore allocate memory). Therefore, there are some (obvious?) limitations to where auto can be used:

image

The mechanism used by the compiler for type-deduction is the same one used to deduce parameter types for template functions. Because of this, the object-type deduced for an auto object may not be exactly what the programmer expects.

The rules are as follows:

  • The deduced type will be a new object.
  • If the initialiser is a reference-to-object, the reference is ignored (since a reference is just an alias for an object).
  • Any const-volatile (cv)-qualifiers on the initialiser are ignored (since the cv-qualifiers are a property of the initialiser, not the new object).
  • Arrays are degenerated into pointer types.

image

We can cv-qualify the deduced type separately, if required. The cv-qualifiers are applied to the new object – after its type has been deduced.

image

If we reference-qualify the auto-deduced type the rules change:

  • The deduced type will now be a reference the initialiser object.
  • Any cv-qualifiers of the initialiser will be maintained on the deduced type (since a reference cannot be less restrictive than its referent; although it can be more restrictive).
  • If the initialiser is an array the deduced type is a reference-to-array type, not a pointer.

image

Returning to our original example, we can simplify the code (considerably) with the use of auto.

image

Additionally, the use of auto allows us a degree of flexibility in our code for future modifications:

image

More information

Can’t wait? Download the full set of articles as a PDF, here.

To learn more about Feabhas’ Modern C++ training courses, click here.

Glennan Carnie
Dislike (0)
Website | + posts

Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry.

He specialises in C++, UML, software modelling, Systems Engineering and process development.

About Glennan Carnie

Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry. He specialises in C++, UML, software modelling, Systems Engineering and process development.
This entry was posted in C/C++ Programming and tagged , , , , . Bookmark the permalink.

6 Responses to Bitesize Modern C++ : auto

  1. Egil Hansson says:

    “C++ is a strongly-typed language, that is, you must explicitly declare the type of every object before use.”

    That's not really what most people mean by “strongly typed”. F# and Haskell are even more strongly typed, but you don't need to declare the type of all variables due to type inference. I would rather say that (classical) C++ is *explicitly* typed.

    Like (0)
    Dislike (1)
  2. Philippe says:

    Bonjour,
    I guess it could be useful to say a word about usage of auto in the range for loop. For example :
    1 - for (auto x : myVector) {...}
    2 - for (auto &x : myVector) {...}
    3 - for (const auto &x : myVector) {...}
    Best regards, Philippe

    Like (1)
    Dislike (0)
  3. Oh yes - but that's coming in another article, later 🙂

    Like (0)
    Dislike (1)
  4. Agreed. It's a typo; I meant to say 'statically typed'. I've edited the article appropriately.

    Thanks for the fix!

    Like (1)
    Dislike (0)
  5. Egil Hansson says:

    To be somewhat pedantic: To be statically typed does not mean that I you need to declare the types of all variables – just that the type checking happens at compile time. To use the same examples as above: F# and Haskell are statically typed, but you don't need to declare the types of all variables (their types can be inferred from how they're used). 🙂

    Like (0)
    Dislike (0)
  6. Really helpful and amazing tips. Thanks

    Like (0)
    Dislike (0)

Leave a Reply