Recommended blogs (PL)

I came upon a similar piece of code during an IRC discussion. While I am certain that some may consider this example trivial, I admit that the correct answer eluded me even after I verified the result with the compiler – it wasn’t until I checked the standard that it became clear.

The line foo(global); doesn’t cause the foo::foo(int) constructor to run, instead causing the default one to be executed. Why is that?

The answer is fairly simple, if vexing, as was spoilt in the title: the C syntax rules, that C++ was saddled with, declare that

N4140 § 6.8 [stmt.ambig] / 1
An expression-statement with a function-style explicit type conversion ([expr.type.conv]) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

It then follows with an example that depicts a nearly identical problem:

This is exactly the same principle that allows the Most Vexing Parse to exist, and that drove the standards committee to design mostly uniform initialiation added in C++11 (and made even less uniform in C++17).

In this case, it meant that foo(global); declared a new local variable called global, shadowing the global global variable. The parentheses here were entirely optional and the meaning of this declaration was identical to foo global;.