By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,233 Members | 1,880 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,233 IT Pros & Developers. It's quick & easy.

A question on variable declarations/initializations

P: n/a
Hi,

consider the following program:

// --------------
class A
{
public:
A(int i) { }
};

class B
{
public:
B(const A&) { }
void f(int) const { }
};

int main()
{
int i(1);

// Declaring a variable v of type B, initialized with A(i):
B v(A(i)); // Nope, this is not producing the intended behaviour, see
error messages below
// Working alternatives:
// 1) B v((A)(i));
// 2) B v(i);
// 3) B v(1);
// 4) B v = B(A(i));

v.f(i); // Sun Workshop 5.2: B(*)(A) is not a structure type
// GCC 3.3.1: request for member b in b(A), which
// is of non-aggregate type B()(A)

return 0;
}

// --------------

As far as I understand, "B v(A(i));" is interpreted as a "pointer v to a
function taking a parameter of type A and returning B". In that case,
naturally, f cannot be called on v.

I don't understand, however, why "B v(A(i));" shouldn't equally well be seen
as "variable v of type B, initialized with the temporary A(i)". For example,
what's the difference to alternative 1), "B v((A)(i));" ?

Do I miss something trivial? I would appreciate if someone could elaborate
in detail on how this declaration is interpreted.

Many thanks,
Andreas
Jul 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Andreas Wachowski wrote:
Hi,

consider the following program:

// --------------
class A
{
public:
A(int i) { }
};

class B
{
public:
B(const A&) { }
void f(int) const { }
};

int main()
{
int i(1);

// Declaring a variable v of type B, initialized with A(i):
B v(A(i)); // Nope, this is not producing the intended behaviour, see
error messages below
// Working alternatives:
// 1) B v((A)(i));
// 2) B v(i);
// 3) B v(1);
// 4) B v = B(A(i));

v.f(i); // Sun Workshop 5.2: B(*)(A) is not a structure type
// GCC 3.3.1: request for member b in b(A), which
// is of non-aggregate type B()(A)

return 0;
}

// --------------

As far as I understand, "B v(A(i));" is interpreted as a "pointer v to a
function taking a parameter of type A and returning B". In that case,
naturally, f cannot be called on v.

I don't understand, however, why "B v(A(i));" shouldn't equally well be seen
as "variable v of type B, initialized with the temporary A(i)". For example,
what's the difference to alternative 1), "B v((A)(i));" ?

Do I miss something trivial? I would appreciate if someone could elaborate
in detail on how this declaration is interpreted.


For whatever reason, v is being interpeted as a function declaration
returning a B.

error from gcc:
request for member `f' in `v', which is of non-class type `B ()(A)'

Comeau gives a similar error.

The interesting thing is that this also works as you expect:

B v(A(1));

I don't understand how A(i) can be considered a type and not an
expression, or even that A(1) is an expression not when A(i) is not.
Also given that 3 compilers all seem to agree, I am a bit perplexed.
Jul 22 '05 #2

P: n/a
Gianni Mariani wrote:
Andreas Wachowski wrote:
Hi,

consider the following program:

// --------------
class A
{
public:
A(int i) { }
};

class B
{
public:
B(const A&) { }
void f(int) const { }
};

int main()
{
int i(1);

// Declaring a variable v of type B, initialized with A(i):
B v(A(i)); // Nope, this is not producing the intended behaviour,
see
error messages below
// Working alternatives:
// 1) B v((A)(i));
// 2) B v(i);
// 3) B v(1);
// 4) B v = B(A(i));

v.f(i); // Sun Workshop 5.2: B(*)(A) is not a structure type
// GCC 3.3.1: request for member b in b(A), which
// is of non-aggregate type B()(A)

return 0;
}

// --------------

As far as I understand, "B v(A(i));" is interpreted as a "pointer v
to a function taking a parameter of type A and returning B". In that
case, naturally, f cannot be called on v.

I don't understand, however, why "B v(A(i));" shouldn't equally well
be seen as "variable v of type B, initialized with the temporary
A(i)". For example, what's the difference to alternative 1), "B
v((A)(i));" ?

Do I miss something trivial? I would appreciate if someone could
elaborate in detail on how this declaration is interpreted.
For whatever reason, v is being interpeted as a function declaration
returning a B.

error from gcc:
request for member `f' in `v', which is of non-class type `B
()(A)'

Comeau gives a similar error.

The interesting thing is that this also works as you expect:

B v(A(1));

I don't understand how A(i) can be considered a type and not an
expression,


B v(A(i)) declares a funcion named v that takes as a parameter named i
an object of type A and returns an object of type B. It's equivalent
to:

B v(A i)
or even that A(1) is an expression not when A(i) is not.


1 can't be the name of a parameter, but i can.

Jul 22 '05 #3

P: n/a
"Rolf Magnus" <ra******@t-online.de> wrote in message
news:cf*************@news.t-online.com...

[snip]
B v(A(i)) declares a funcion named v that takes as a parameter named i
an object of type A and returns an object of type B. It's equivalent
to:

B v(A i)


So far, so good; thanks for the answer. I am still surprised, though, I
don't think I have seen this before. Can someone point me to a section in
the standard (or some book or other source) explaining this, perhaps? How
can one know (i.e. without relying on the compiler's error message) that the
statement "B v(A(i))" will not declare an element v of type B, initialized
with A(i)?

Your help is appreciated!

Thanks in advance, Andreas
Jul 22 '05 #4

P: n/a

"Andreas Wachowski" <an***************@gmx.de> wrote in message news:2o************@uni-berlin.de...
So far, so good; thanks for the answer. I am still surprised, though, I
don't think I have seen this before. Can someone point me to a section in
the standard (or some book or other source) explaining this, perhaps? How
can one know (i.e. without relying on the compiler's error message) that the
statement "B v(A(i))" will not declare an element v of type B, initialized
with A(i)?

It's amplified in section 8.2 of the standard (Ambiguity Resolution). The rule
that when there is an ambiguity between a declaration and an expression, the
declaration wins out.

The ambiguity is if A(i) is a declaration of the parameter i of type A, or a cast
expression A(i), it is resolved as the declaration.

-Ron

Jul 22 '05 #5

P: n/a

"Ron Natalie" <ro*@sensor.com> wrote in message
news:41**********************@news.newshosting.com ...
It's amplified in section 8.2 of the standard (Ambiguity Resolution).

The rule that when there is an ambiguity between a declaration and an expression, the declaration wins out.

The ambiguity is if A(i) is a declaration of the parameter i of type A, or a cast expression A(i), it is resolved as the declaration.


It never even occured to me this could be ambiguous, because I didn't know
you could declare parameters this way. Am I missing something basic, or
obscure?
Jul 22 '05 #6

P: n/a
jeffc wrote:
The ambiguity is if A(i) is a declaration of the parameter i of type
A, or a cast expression A(i), it is resolved as the declaration.


It never even occured to me this could be ambiguous, because I didn't
know you could declare parameters this way. Am I missing something
basic, or obscure?


You're missing that if you declare something like:

A (i);

the parens are superfluous and ignored.

Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.