This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 6 years ago.
I saw a code here at Cpp Quiz [Question #38]
#include <iostream>
struct Foo
{
Foo(int d) : x(d) {}
int x;
};
int main()
{
double x = 3.14;
Foo f( int(x) );
std::cout << f.x << std::endl;
return 0;
}
It is said there that this code is ill-formed because Foo f( int(x) ); will be treated as a function declaration rather than an object declaration of type Foo.
As far as I know, this is an instance of "most vexing parse". My question is what does this syntax int(x) in statement Foo f( int(x) ); mean? So far I only saw function declarations like:
Foo f( int ); and
Foo f( int x );
Is it the same as Foo f( int x );?
what does this syntax int(x) in the statement Foo f( int(x) ); mean?
The parentheses around x are superfluous and will be ignored. So int(x) is the same as int x here, which means a parameter named x with type int.
Is it the same as Foo f( int x );?
Yes. Foo f( int(x) );, is a function declaration which is named f, returns Foo, takes one parameter named x with type int.
Here's the explanation from the standard. [dcl.ambig.res]/1:
(emphasis mine)
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in [stmt.ambig] can also occur in the
context of a declaration. In that context, the choice is between a
function declaration with a redundant set of parentheses around a
parameter name and an object declaration with a function-style cast as
the initializer. Just as for the ambiguities mentioned in
[stmt.ambig], the resolution is to consider any construct that could
possibly be a declaration.
Note: A declaration can be
explicitly disambiguated by adding parentheses around the argument.
The ambiguity can be avoided by use of copy-initialization or
list-initialization syntax, or by use of a non-function-style cast.
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
So, int(x) will be considered as a declaration (of the parameter) rather than a function style cast.
The problem is that, for reasons unknown to me, it's valid to wrap parameter names into parenthesis in prototypes. So
Foo f(int(x));
can be interpreted as
Foo f(int x);
that is considered as
Foo f(int);
The real issue is however that C++ authors, also for reasons unknown to me, decided that it was cool to have two different syntax forms for the almost very same semantic (instance initialization).
This introduces an syntax ambiguity that is "resolved" by saying that "if something can be both a declaration and a definition, then it's a declaration", triggering the trap.
Because of that a C++ parser therefore must be able to parse an arbitrarily large number of tokens before being able to decide what is the semantic meaning of the very first of them.
This apparently wouldn't have been too much of an issue except for compiler writers, but however it means that also who reads C++ code to understand it must be able to do the same, and for we humans this is harder. From that the "most vexing".
Related
Why does the compiler interpret this line as a function definition and not as a variable definition:
Y y(X());
in the following code:
#include <iostream>
struct X {
X() { std::cout << "X"; }
};
struct Y {
Y(const X &x) { std::cout << "Y"; }
void f() { std::cout << "f"; }
};
int main() {
Y y(X());
y.f();
}
VS2010 gives the following error on line "y.f();"
left of '.f' must have class/struct/union
Which part of the standard describes this behavior?
The answer to the following question doesn't give details about it:
Most vexing parse
Consider this :
float foo( int () )
This declares a function foo ( accepting a function returning int ) returning float.
Now read
Y y(X());
as y as function (accepting a function returning X) returning Y
The problem arises due to C++ most vexing parse
Can be solved with :
Y y{ X() }; // requires C++11
or
Y y( ( X() ) );
// ^ ^ notice parenthesis
Update based on edit:
A quote from the standard :
§ 8.2 Ambiguity resolution [dcl.ambig.res]
1 - The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in 6.8 can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in 6.8, the resolution is to consider any construct that could possibly be a declaration a declaration. [Note: a declaration can be explicitly disambiguated by a nonfunction-style cast, by a = to indicate initialization or by removing the redundant parentheses around the parameter name. ]
[Example:
struct S {
S(int);
};
void foo(double a)
{
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
—end example]
Similarly other examples following this.
Most vexing parse problem. Y y(X()) is actually function declaration with name y, that returns Y and receives argument of type function, that returns X and receives nothing.
It's solved in C++11 with usage of {} for construct object.
This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 6 years ago.
I saw a code here at Cpp Quiz [Question #38]
#include <iostream>
struct Foo
{
Foo(int d) : x(d) {}
int x;
};
int main()
{
double x = 3.14;
Foo f( int(x) );
std::cout << f.x << std::endl;
return 0;
}
It is said there that this code is ill-formed because Foo f( int(x) ); will be treated as a function declaration rather than an object declaration of type Foo.
As far as I know, this is an instance of "most vexing parse". My question is what does this syntax int(x) in statement Foo f( int(x) ); mean? So far I only saw function declarations like:
Foo f( int ); and
Foo f( int x );
Is it the same as Foo f( int x );?
what does this syntax int(x) in the statement Foo f( int(x) ); mean?
The parentheses around x are superfluous and will be ignored. So int(x) is the same as int x here, which means a parameter named x with type int.
Is it the same as Foo f( int x );?
Yes. Foo f( int(x) );, is a function declaration which is named f, returns Foo, takes one parameter named x with type int.
Here's the explanation from the standard. [dcl.ambig.res]/1:
(emphasis mine)
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in [stmt.ambig] can also occur in the
context of a declaration. In that context, the choice is between a
function declaration with a redundant set of parentheses around a
parameter name and an object declaration with a function-style cast as
the initializer. Just as for the ambiguities mentioned in
[stmt.ambig], the resolution is to consider any construct that could
possibly be a declaration.
Note: A declaration can be
explicitly disambiguated by adding parentheses around the argument.
The ambiguity can be avoided by use of copy-initialization or
list-initialization syntax, or by use of a non-function-style cast.
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
So, int(x) will be considered as a declaration (of the parameter) rather than a function style cast.
The problem is that, for reasons unknown to me, it's valid to wrap parameter names into parenthesis in prototypes. So
Foo f(int(x));
can be interpreted as
Foo f(int x);
that is considered as
Foo f(int);
The real issue is however that C++ authors, also for reasons unknown to me, decided that it was cool to have two different syntax forms for the almost very same semantic (instance initialization).
This introduces an syntax ambiguity that is "resolved" by saying that "if something can be both a declaration and a definition, then it's a declaration", triggering the trap.
Because of that a C++ parser therefore must be able to parse an arbitrarily large number of tokens before being able to decide what is the semantic meaning of the very first of them.
This apparently wouldn't have been too much of an issue except for compiler writers, but however it means that also who reads C++ code to understand it must be able to do the same, and for we humans this is harder. From that the "most vexing".
This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 6 years ago.
I saw a code here at Cpp Quiz [Question #38]
#include <iostream>
struct Foo
{
Foo(int d) : x(d) {}
int x;
};
int main()
{
double x = 3.14;
Foo f( int(x) );
std::cout << f.x << std::endl;
return 0;
}
It is said there that this code is ill-formed because Foo f( int(x) ); will be treated as a function declaration rather than an object declaration of type Foo.
As far as I know, this is an instance of "most vexing parse". My question is what does this syntax int(x) in statement Foo f( int(x) ); mean? So far I only saw function declarations like:
Foo f( int ); and
Foo f( int x );
Is it the same as Foo f( int x );?
what does this syntax int(x) in the statement Foo f( int(x) ); mean?
The parentheses around x are superfluous and will be ignored. So int(x) is the same as int x here, which means a parameter named x with type int.
Is it the same as Foo f( int x );?
Yes. Foo f( int(x) );, is a function declaration which is named f, returns Foo, takes one parameter named x with type int.
Here's the explanation from the standard. [dcl.ambig.res]/1:
(emphasis mine)
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in [stmt.ambig] can also occur in the
context of a declaration. In that context, the choice is between a
function declaration with a redundant set of parentheses around a
parameter name and an object declaration with a function-style cast as
the initializer. Just as for the ambiguities mentioned in
[stmt.ambig], the resolution is to consider any construct that could
possibly be a declaration.
Note: A declaration can be
explicitly disambiguated by adding parentheses around the argument.
The ambiguity can be avoided by use of copy-initialization or
list-initialization syntax, or by use of a non-function-style cast.
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
So, int(x) will be considered as a declaration (of the parameter) rather than a function style cast.
The problem is that, for reasons unknown to me, it's valid to wrap parameter names into parenthesis in prototypes. So
Foo f(int(x));
can be interpreted as
Foo f(int x);
that is considered as
Foo f(int);
The real issue is however that C++ authors, also for reasons unknown to me, decided that it was cool to have two different syntax forms for the almost very same semantic (instance initialization).
This introduces an syntax ambiguity that is "resolved" by saying that "if something can be both a declaration and a definition, then it's a declaration", triggering the trap.
Because of that a C++ parser therefore must be able to parse an arbitrarily large number of tokens before being able to decide what is the semantic meaning of the very first of them.
This apparently wouldn't have been too much of an issue except for compiler writers, but however it means that also who reads C++ code to understand it must be able to do the same, and for we humans this is harder. From that the "most vexing".
This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 6 years ago.
I saw a code here at Cpp Quiz [Question #38]
#include <iostream>
struct Foo
{
Foo(int d) : x(d) {}
int x;
};
int main()
{
double x = 3.14;
Foo f( int(x) );
std::cout << f.x << std::endl;
return 0;
}
It is said there that this code is ill-formed because Foo f( int(x) ); will be treated as a function declaration rather than an object declaration of type Foo.
As far as I know, this is an instance of "most vexing parse". My question is what does this syntax int(x) in statement Foo f( int(x) ); mean? So far I only saw function declarations like:
Foo f( int ); and
Foo f( int x );
Is it the same as Foo f( int x );?
what does this syntax int(x) in the statement Foo f( int(x) ); mean?
The parentheses around x are superfluous and will be ignored. So int(x) is the same as int x here, which means a parameter named x with type int.
Is it the same as Foo f( int x );?
Yes. Foo f( int(x) );, is a function declaration which is named f, returns Foo, takes one parameter named x with type int.
Here's the explanation from the standard. [dcl.ambig.res]/1:
(emphasis mine)
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in [stmt.ambig] can also occur in the
context of a declaration. In that context, the choice is between a
function declaration with a redundant set of parentheses around a
parameter name and an object declaration with a function-style cast as
the initializer. Just as for the ambiguities mentioned in
[stmt.ambig], the resolution is to consider any construct that could
possibly be a declaration.
Note: A declaration can be
explicitly disambiguated by adding parentheses around the argument.
The ambiguity can be avoided by use of copy-initialization or
list-initialization syntax, or by use of a non-function-style cast.
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
So, int(x) will be considered as a declaration (of the parameter) rather than a function style cast.
The problem is that, for reasons unknown to me, it's valid to wrap parameter names into parenthesis in prototypes. So
Foo f(int(x));
can be interpreted as
Foo f(int x);
that is considered as
Foo f(int);
The real issue is however that C++ authors, also for reasons unknown to me, decided that it was cool to have two different syntax forms for the almost very same semantic (instance initialization).
This introduces an syntax ambiguity that is "resolved" by saying that "if something can be both a declaration and a definition, then it's a declaration", triggering the trap.
Because of that a C++ parser therefore must be able to parse an arbitrarily large number of tokens before being able to decide what is the semantic meaning of the very first of them.
This apparently wouldn't have been too much of an issue except for compiler writers, but however it means that also who reads C++ code to understand it must be able to do the same, and for we humans this is harder. From that the "most vexing".
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?
Most vexing parse: why doesn't A a(()); work?
This one gets me mad. Maybe its just too simple.
struct Foo
{
Foo() {}
Foo(const Foo& f) {}
void work() {}
};
int main()
{
Foo f( Foo() );
f.work();
}
GCC 4.6 gives me:
error: request for member ‘work’ in ‘f’, which is of non-class type ‘Foo(Foo (*)())’
After elision of the copy operation the effective code might look like:
int main()
{
Foo f;
f.work();
}
But why can't i call work() ??
Edit:
Yes, duplicate (see below). Didn't find the original post when search first because the source of the symptoms of this is located where i didn't expect that.
Because Foo f( Foo() ); is a function declaration.
I think you want: Foo f;
Or in case you want to copy-construct:
Foo f( (Foo()) );
f is effectively a function declaration within main function.
Try
Foo f((Foo())); // to make the definition of f explicit enough.
n3337 8.2
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in 6.8 can also occur in the context
of a declaration. In that context, the choice is between a function
declaration with a redundant set of parentheses around a parameter
name and an object declaration with a function-style cast as the
initializer. Just as for the ambiguities mentioned in 6.8, the
resolution is to consider any construct that could possibly be a
declaration a declaration. [ Note: A declaration can be explicitly
disambiguated by a nonfunction-style cast, by an = to indicate
initialization or by removing the redundant parentheses around the
parameter name. — end note ] [ Example:
struct S {
S(int);
};
void foo(double a) {
S w(int(a));
//function declaration
S x(int());
//function declaration
S y((int)a);
//object declaration
S z = int(a);
//object declaration
}
— end example ]
C++ parser interprets Foo f(Foo()); expression as the function declaration with the signature Foo(Foo(*)()), i.e. a function returning Foo and taking a function pointer to the function returning Foo. Adding explicit parenthesis around the argument like so Foo f((Foo())); will resolve the ambiguity. But consider actually just doing Foo f; which avoids redundant code.