Consider if the program were like so:
typedef struct A { int m; } A;
int main() { A a( A() ); }
This would be valid C, and there is only one possible interpretation allowed by the grammar of C: a
is declared as a function. C only allows initialization using =
(not parentheses), and does not allow A()
to be interpreted as an expression. (Function-style casts are a C++-only feature.) This is not a "vexing parse" in C.
The grammar of C++ makes this example ambiguous, as Wikipedia points out. However, if you want C++ to give this program the same meaning as C, then, obviously, C++ compilers are going to have to interpret a
as a function just like C compilers. Sure, C++ could have changed the meaning of this program, making a
the definition of a variable of type A
. However, incompatibilities with C were introduced into C++ only when there was a good reason to do it, and I would imagine that Stroustrup particularly wanted to avoid potentially silent breakages such as this, as they would cause great frustration for C users migrating to C++.
Thus, C++ interprets it as a function declaration too, and not a variable definition; and more generally, adopted the rule that if something that looks like a function-style cast can be interpreted as a declaration instead in its syntactic context, then it shall be. This eliminates potential for incompatibility with C for all vexing-parse situations, by ensuring that the interpretation that is not available in C (i.e. the one involving a function-style cast) is not taken.
Cfront 2.0 Selected Readings (page 1-42) mentions the C compatibility issue in the case of expression-declaration ambiguity, which is a related type of most vexing parse.