Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

trick question regarding declaration syntax in C++

Tags:

c++

syntax

Have a look here: In the following code, what would be the type of b?

struct A {
    A (int i) {}
};

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

int main () {
    int i = 1;
    B b(A(i)); // what would be the type of b
    return 0;
}

I'll appreciate it if anybody could explain to me thoroughly why would such syntax exist :)

Thanks.

like image 625
rmn Avatar asked Sep 04 '09 15:09

rmn


2 Answers

One of C's warts (and C++ inherits it (and makes it worse)) is that there is no special syntax for introducing a declaration. This means declarations often look like executable code. Another example:

A * a;

Is this multiplying A by a, or is it declaring something? In order to make sense of this line you have to know that A is the name of a type.

The basic rule in C++ is that if something can be parsed as a declaration, it is. In this instance it leads to a strange and surprising result. Function declarations look a lot like function calls, and in particular the ( after the A can be thought of in a couple of ways.

You can get around this in this example with extra parenthesis that remove the compiler's ability to parse the code as a declaration.

B b((A(i)));

In C this isn't ambiguous because there is no function style of constructor call because there are no constructors. A is either the name of a type, or it's the name of a function. It can't be both.

like image 135
Omnifarious Avatar answered Oct 30 '22 09:10

Omnifarious


It is a local function declaration according to C++ Standard 8.2/1. You could use implicit form of constructor to avoid this or the following:

B b(A(i)); // is equal to B b( A i );

// ---

// to declare variable of type B write:
B b = A(i);
// explicit form if you want:
B b( static_cast<A>(A(i)) );
// or
B b( (A)i );

C++ Standard 8.2/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 con- struct that could possibly be a declaration a declaration.

like image 24
Kirill V. Lyadvinsky Avatar answered Oct 30 '22 09:10

Kirill V. Lyadvinsky