C++'s Most Vexing Parse: A Common Mistake

“I thought I was calling a constructor… but C++ had other plans.” That’s C++’s Most Vexing Parse. ⚡ I wrote: Timer t(); Expecting it to call the constructor and create an object. But C++ quietly treated it as a function declaration returning a Timer. 😅 ✅ Correct way: Timer t{}; // or Timer t; Or if you prefer smart pointers: auto t = std::make_unique<Timer>(); Even something as simple as parentheses can confuse the compiler — and you. #cpp #cplusplus #Cpp #Cplusplus #programming #learninpublic #developers #coding

  • text

Given that Timer has default constructor just using "Timer t;" is well-defined and in my opinition is a better practice as this is an explicit message to the compiler to default-initialize an object, whereas using "{}" will imply value-initialization as a level of indirection to get to default-initialization (compiler will have to check whether the type is an aggregate or if zero-initialization can be used)

Teodorescu Mihail

Senior Embedded Software Engineer/Senior Software Engineer

6mo

The compiler was not confused. Is just that that C and C++ compilers allow the declaration of functions inside other functions and with: Timer t() you declared a local function inside the demo function. Is just working as intended. If you wonder why Compilers of C and C++ allow the declaration of a function inside another function, well, you can use a function defined in another file, without using #include <other_file_header> this way but is not considered a Best practice our days. With Timer t{} you declared and initialized an object of the type Timer so the constructor was called.

Like
Reply

You can use this alternative auto t = Timer(); Starting from C++17 there is no movement or copying.

Like
Reply
See more comments

To view or add a comment, sign in

Explore content categories