There are two main ways to declare and initialise variables with automatic or static storage in C++: with `='; and with parentheses.

Some C++ programmers prefer to use copyconstructor-style initialisation syntax for clarity because it is the copy constructor that's invoked in both cases, not the assignment operator as one might expect from the use of the equals sign.

But I think clarity is the complete opposite of what you get. It can cause problems where you do not expect them, leading to complicated diagnostics:

Although the linker error makes sense if you know that you have declared a function and never defined it, the diagnostic does not really help you fix the problem if you did not see this coming and expected x to be equal to 0.

"Wait, what. I've declared a function?"

Yep! The only difference between a function declaration int(T) and a temporary construction int(x) is that T is a type whereas x is an expression. So:

In the last case above, because the int() has nothing inside the parentheses it can be parsed as either, and function declaration is always assumed in C++ where it's possible.

There are plenty of cases where a type simply cannot be in a situation like this, and in the other cases you can hack around it by forcing the declaration to become an expression with extra parentheses:

Still, even if just because of this, I avoid "int x(3);" and instead prefer good-old equals-syntax which, although it doesn't actually invoke the assignment operator, at least does what it says it does: it declares and initialises an integer variable called x, equal to 3:

Stick to this syntax and you won't have any trouble; problem solved. 🙂

Further reading