Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Variable declaration or function prototype

Reply
Thread Tools

Variable declaration or function prototype

 
 
Andrew Ward
Guest
Posts: n/a
 
      09-10-2003
Hi All,
Could someone please tell me why this code does not compile.

struct A {};

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

struct C {
C(B &) {}
void f() {}
};

void foo() {
A a;
C c(B(a));
c.f();
}

If I change foo() to the following then it does compile:

void foo() {
A a;
B b(a);
C c(b);
c.f();
}

I would have thought that you could pass the B temporary into C's
constructor like that?

Andy


 
Reply With Quote
 
 
 
 
White Wolf
Guest
Posts: n/a
 
      09-10-2003
Andrew Ward wrote:
> Hi All,
> Could someone please tell me why this code does not compile.
>
> struct A {};
>
> struct B {
> B(A &) {}
> };
>
> struct C {
> C(B &) {}
> void f() {}
> };
>
> void foo() {
> A a;
> C c(B(a));
> c.f();
> }
>
> If I change foo() to the following then it does compile:
>
> void foo() {
> A a;
> B b(a);
> C c(b);
> c.f();
> }
>
> I would have thought that you could pass the B temporary into C's
> constructor like that?


You could if you did write the constructors properly:

B(A const &);

C(B const &);

Temporaries cannot be bound to non-const references.

--
WW aka Attila


 
Reply With Quote
 
 
 
 
Jim Fischer
Guest
Posts: n/a
 
      09-11-2003
Andrew Ward wrote:
> Hi All,
> Could someone please tell me why this code does not compile.


Unless I'm mistaken, the statement

C c(B(a));

is a function declaration (prototype). It declares a function named 'c'
that is passed (by value) a class B object, and returns (by value) a
class C object. This statement does not instantiate a class C object
named 'c'.

--
Jim

To reply by email, remove "link" and change "now.here" to "yahoo"
jfischer_link5809{at}now.here.com


 
Reply With Quote
 
Andrew Ward
Guest
Posts: n/a
 
      09-11-2003

"White Wolf" <> wrote in message
news:bjodhd$70o$...
> Andrew Ward wrote:
> > Hi All,
> > Could someone please tell me why this code does not compile.
> >
> > struct A {};
> >
> > struct B {
> > B(A &) {}
> > };
> >
> > struct C {
> > C(B &) {}
> > void f() {}
> > };
> >
> > void foo() {
> > A a;
> > C c(B(a));
> > c.f();
> > }
> >
> > If I change foo() to the following then it does compile:
> >
> > void foo() {
> > A a;
> > B b(a);
> > C c(b);
> > c.f();
> > }
> >
> > I would have thought that you could pass the B temporary into C's
> > constructor like that?

>
> You could if you did write the constructors properly:
>
> B(A const &);
>
> C(B const &);
>
> Temporaries cannot be bound to non-const references.
>
> --
> WW aka Attila
>
>


Even when I try passing by const & like you suggested it still does not
work, the error message is:

error C2228: left of '.f' must have class/struct/union type
type is 'overloaded-function'

Maybe Jim Fischer's suggestion is correct?

Andy


 
Reply With Quote
 
Kevin Goodsell
Guest
Posts: n/a
 
      09-11-2003
Andrew Ward wrote:

> "White Wolf" <> wrote in message
> news:bjodhd$70o$...
>
>>Andrew Ward wrote:
>>
>>>Hi All,
>>>Could someone please tell me why this code does not compile.
>>>
>>>struct A {};
>>>
>>>struct B {
>>> B(A &) {}
>>>};
>>>
>>>struct C {
>>> C(B &) {}
>>> void f() {}
>>>};
>>>
>>>void foo() {
>>> A a;
>>> C c(B(a));
>>> c.f();
>>>}
>>>
>>>If I change foo() to the following then it does compile:
>>>
>>>void foo() {
>>> A a;
>>> B b(a);
>>> C c(b);
>>> c.f();
>>>}
>>>
>>>I would have thought that you could pass the B temporary into C's
>>>constructor like that?

>>
>>You could if you did write the constructors properly:
>>
>>B(A const &);
>>
>>C(B const &);
>>
>>Temporaries cannot be bound to non-const references.
>>
>>--
>>WW aka Attila
>>
>>

>
>
> Even when I try passing by const & like you suggested it still does not
> work, the error message is:
>
> error C2228: left of '.f' must have class/struct/union type
> type is 'overloaded-function'
>
> Maybe Jim Fischer's suggestion is correct?
>


In fact, they are both correct (I think). Attila's answer is what I
would have said. The problem Jim pointed out is a bit more insidious:

C c(B(a));

I don't know the exact rule, but basically because this *could* be
either a function declaration or an object instantiation, the former
wins. It's equivalent to

C c(B a);

With a pair of superfluous parenthesis.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

 
Reply With Quote
 
Jim Fischer
Guest
Posts: n/a
 
      09-11-2003
Kevin Goodsell wrote:
>> Maybe Jim Fischer's suggestion is correct?
>>

>
> In fact, they are both correct (I think). Attila's answer is what I
> would have said. The problem Jim pointed out is a bit more insidious:
>
> C c(B(a));
>
> I don't know the exact rule, but basically because this *could* be
> either a function declaration or an object instantiation, the former
> wins. It's equivalent to
>
> C c(B a);
>
> With a pair of superfluous parenthesis.


I'm 99.999% sure the statement 'C c(B(a));' is a function declaration
(see: 8.2/1 in ISO 14882:199.

FWIW, you can disambiguate the interior subexpression 'B(a)' by wrapping
it in parens, e.g.,

C c( (B(a)) );

Now the compiler treats 'B(a)' as an object declaration that uses a
function-style type cast as the initializer (and not a function
declaration with a redundant set of parens around a parameter name).
IOW, 'B(a)' is now considered an invocation of B::B(A&). Consequently,
the surrounding expression - i.e., the declaration of 'c' - is also
treated as an object declaration with a function-style type cast as the
initializer.

Caveat: Making this change to your code introduces another problem.
Specifically, the unnamed, temporary class B object that results from
the invocation of B::B(A&) cannot be bound to a non-const reference. So
the construction of 'c' cannot occur because class C does not have a
suitable constructor - e.g., C::C(B&) cannot be used because B& is a
non-const reference. There are (at least) two fixes for this problem:

1) Modify the existing class C ctor

C(B &) { }

so its reference is const-valued

C(const B &) { }

or,

2) Add a second ctor to class C; one with a suitable const reference
argument:

class C {
C (B &) { }
C (const B &) { }
void f () { }
}

--
Jim

To reply by email, remove "link" and change "now.here" to "yahoo"
jfischer_link5809{at}now.here.com


 
Reply With Quote
 
White Wolf
Guest
Posts: n/a
 
      09-11-2003
Andrew Ward wrote:
[SNIP]
> Even when I try passing by const & like you suggested it still does
> not work, the error message is:
>
> error C2228: left of '.f' must have class/struct/union type
> type is 'overloaded-function'
>
> Maybe Jim Fischer's suggestion is correct?


Not maybe. Definitely. I am ashamed not seeing it - especially because
I have got my copy - of the book mentioning this "gotcha" - signed by the
author. Well, well well. Time for me to look for a job where no brains are
required.

--
WW aka Attila


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What's the difference between function declaration and function prototype? Hill Pang C Programming 8 09-05-2012 08:21 AM
Class prototype vs C function prototype June Lee C++ 2 04-13-2008 08:17 PM
function prototype vs function declaration Ravishankar S C Programming 44 12-23-2007 11:40 AM
Variable declaration taken as a function pointer declaration Bolin C++ 4 12-02-2005 05:28 PM
prototype declaration not variable definition John Harrison C++ 4 08-07-2003 05:37 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57