Another case of the "unparseable situation"?

N

Noah Roberts

`type_x var();` is "unparseable" in that it's impossible to tell if this
is a function declaration or an instantiation of a variable using the
default constructor. Thus the standard tells the compiler which to
pick. The other day I helped a coworker find a problem that ultimately
ended up being something possibly similar?

type_x var1 = ....;
{
type_y(var);
}

This happened because he was testing to see if the construction of
"type_y" threw an exception and the macro in Boost.Test that does this
turns into something quite similar to the above.

What the compiler did here surprised the hell out of me. It decided
that the line meant, "build a new type_y called 'var' and use the
default constructor."

I also tried some other variations without using the macro and this also
did the same thing:

type_x var = ....;
type_y(var);

This one surprises me more as it should be easy to tell now that it's
illegal to have two 'var' instances in the same scope.

Is this correct behavior or a broken compiler?
 
P

Paul

Noah Roberts said:
`type_x var();` is "unparseable" in that it's impossible to tell if this
is a function declaration or an instantiation of a variable using the
default constructor. Thus the standard tells the compiler which to pick.
The other day I helped a coworker find a problem that ultimately ended up
being something possibly similar?
Is that a question?
type_x var1 = ....;
What is this elipsis?
You assign something to var1. But it seems to be an elipsis.

{
type_y(var);
}
I dont think the curly braces are doing anything here.
This seems like a function call,maybe a constructor IDK because type_y is
not defined.

This happened because he was testing to see if the construction of
"type_y" threw an exception and the macro in Boost.Test that does this
turns into something quite similar to the above.

What the compiler did here surprised the hell out of me. It decided that
the line meant, "build a new type_y called 'var' and use the default
constructor."

I also tried some other variations without using the macro and this also
did the same thing:

type_x var = ....;
type_y(var);

This one surprises me more as it should be easy to tell now that it's
illegal to have two 'var' instances in the same scope.

Is this correct behavior or a broken compiler?
Dunno it seems a bit dodgy to me.
 
B

Balog Pal

Noah Roberts said:
I also tried some other variations without using the macro and this also
did the same thing:

type_x var = ....;
type_y(var);

This one surprises me more as it should be easy to tell now that it's
illegal to have two 'var' instances in the same scope.

Is this correct behavior or a broken compiler?

Seem so.

- --

struct A { };
struct B {
explicit B(A);
};

void bar(B);

void foo()
{
A a;
B(a);
bar(B(a));
}
- --
"ComeauTest.c", line 12: error: "a" has already been declared in the current
scope
B(a);
^

"ComeauTest.c", line 12: error: no default constructor exists for class "B"
B(a);
^
- ---

If you comment out the offending line it compiles. B(a); appears working as
expected as expression, but where object declaration is allowed, treated as
that. I'm lazy to look up what allows () around identifier (name of the
object being created) but recall some earlier conversation that it actually
follows from the grammar, that is supposed to allow function pointers and
such. Making redundant outer () just stripped. Any amount of them.
 
V

Victor Bazarov

`type_x var();` is "unparseable" in that it's impossible to tell if this
is a function declaration or an instantiation of a variable using the
default constructor. Thus the standard tells the compiler which to pick.
The other day I helped a coworker find a problem that ultimately ended
up being something possibly similar?

type_x var1 = ....;
{
type_y(var);
}

This happened because he was testing to see if the construction of
"type_y" threw an exception and the macro in Boost.Test that does this
turns into something quite similar to the above.

What the compiler did here surprised the hell out of me. It decided that
the line meant, "build a new type_y called 'var' and use the default
constructor."

I also tried some other variations without using the macro and this also
did the same thing:

type_x var = ....;
type_y(var);

This one surprises me more as it should be easy to tell now that it's
illegal to have two 'var' instances in the same scope.

Is this correct behavior or a broken compiler?

The rule, which you already alluded to, in the Standard: if it can be
interpreted as a *declaration*, it *shall* be interpreted as a
declaration (over a regular expression). The parentheses in

<sometype> ( <identifier> );

are optional, and you can have as many as you'd like, it's still a
*declaration* of a variable named <identifier> and its type is
<sometype>. Just like

<sometype> <identifier> ();

is a syntax for a declaration of a function (since parentheses here
serve a special purpose - to designate and enclose the argument list).

V
 
J

Johannes Schaub (litb)

Noah said:
`type_x var();` is "unparseable" in that it's impossible to tell if this
is a function declaration or an instantiation of a variable using the
default constructor. Thus the standard tells the compiler which to
pick.

That's incorrect. The given sequence of tokens cannot be parsed as a
variable declaration. Even if you wanted to. The grammar for initializer in
a simple declaration does not allow "()".
type_x var1 = ....;
{
type_y(var);
}

Yes, the parenthesis is redundant here, and the line in question actually is
equivalent to

type_y var;

This happened because he was testing to see if the construction of
"type_y" threw an exception and the macro in Boost.Test that does this
turns into something quite similar to the above.

What the compiler did here surprised the hell out of me. It decided
that the line meant, "build a new type_y called 'var' and use the
default constructor."

I also tried some other variations without using the macro and this also
did the same thing:

type_x var = ....;
type_y(var);

Yes, this is semantically ill-formed because you have two variables having
the same name.
 
N

Noah Roberts

The rule, which you already alluded to, in the Standard: if it can be
interpreted as a *declaration*, it *shall* be interpreted as a
declaration (over a regular expression). The parentheses in

<sometype> ( <identifier> );

are optional, and you can have as many as you'd like, it's still a
*declaration* of a variable named <identifier> and its type is
<sometype>. Just like

<sometype> <identifier> ();

is a syntax for a declaration of a function (since parentheses here
serve a special purpose - to designate and enclose the argument list).

K, figured that was what was happening. Thanks.
 
J

Juha Nieminen

Paul said:
What is this elipsis?
You assign something to var1. But it seems to be an elipsis.


I dont think the curly braces are doing anything here.

You are being as helpful as always.
 
P

Paul

Juha Nieminen said:
You are being as helpful as always.
I was trying to extract a better explanation of what exactly the question
was.

The code presented re:

type_x var1 = ....;
{
type_y(var);
}

Did not examplify any problem in the form as expressed by the initial
statement re:
"`type_x var();` is "unparseable" in that it's impossible to tell if this
is a function declaration or an instantiation of a variable using the
default constructor. "


I was not trying to be unhelpfull, Im sorry if it came across that way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top