In the following code
#include <map>
#include <string>
struct P2d {
double x, y;
P2d(double x, double y) : x(x), y(y) {}
};
double bar() {
std::map<std::string, int> m;
//P2d lp = P2d(double(m["x"]), double(m["y"])); // this works
P2d lp(double(m["x"]), double(m["y"]));
return lp.x;
}
all compilers I tested agree the code (un-commented version) is invalid but I fail to see why the definition
P2d lp(<double>, <double>);
that I used is not acceptable.
I remember the rule was "if it can be both a function declaration and a definition then it's a declaration" but I expected that if it cannot be a declaration then it should be interpreted as a definition instead of giving an error.
What am I missing?
Hold on to your chair since it's pretty funny. As you surely know C++ allows array function parameters. And so you can get this:
void foo(double s[2], double b[2]);
This is obvious. A possible obfuscation step is to replace spaces between type and parameters name which is also allowed:
void foo(double(s[2]),double(b[2]));
Now you can imagine what can be done pretty simply - replace numbers with const char*
. Like this:
void foo(double(s["x"]),double(b["y"]));
This is invalid function declaration, nevertheless it is seen by the compilers as exactly this - declaration. This is exactly what happened to your code.
EDIT:
The whole problem seems to arise from not strict enough restrictions on array declarators in C++ standard. The only requirement for array 'size' parameter is being constexpr
value which is supposed to be converted to std::size_t
(but it is not checked on the level of syntax analysis, it is done later on). For more on that check this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With