Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Function declared before call but defined after - compilation fails

Reply
Thread Tools

Function declared before call but defined after - compilation fails

 
 
johnbrown105@hotmail.com
Guest
Posts: n/a
 
      05-16-2007
Hello All,

I am doing another exercise (I repeat, *exercise*). The (irrelevant to
this
discussion) point is to show that "You can inject a friend declaration
into
a namespace by declaring it within an enclosed class". I have done
this
successfully, but please consider the following program:

//: C10:FriendInjection.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
namespace Me {
class Us {
//...
public:
friend void you();
};
}
// 1
void Me::you(){}

int main() {
Me::you();
return 0;
}

// 2
// defining you() after main() does not compile
// void Me::you(){}
///:~
/////////////////////////////////////////////////////////////////////////

If Me::you() is *defined* at (2) after the call in main(), gcc 4.1.1
says:
"error: 'you' is not a member of 'Me'". If, instead, Me::you is
*defined* at (1),
then it compiles.

MSVC++ Express compiles it either way without a problem, as expected.

Surely this is a bug in gcc?

 
Reply With Quote
 
 
 
 
Howard
Guest
Posts: n/a
 
      05-16-2007

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> Hello All,
>
> I am doing another exercise (I repeat, *exercise*). The (irrelevant to
> this
> discussion) point is to show that "You can inject a friend declaration
> into
> a namespace by declaring it within an enclosed class". I have done
> this
> successfully, but please consider the following program:
>
> //: C10:FriendInjection.cpp
> // From Thinking in C++, 2nd Edition
> // Available at http://www.BruceEckel.com
> // (c) Bruce Eckel 2000
> // Copyright notice in Copyright.txt
> namespace Me {
> class Us {
> //...
> public:
> friend void you();
> };
> }
> // 1
> void Me::you(){}
>
> int main() {
> Me::you();
> return 0;
> }
>
> // 2
> // defining you() after main() does not compile
> // void Me::you(){}
> ///:~
> /////////////////////////////////////////////////////////////////////////
>
> If Me::you() is *defined* at (2) after the call in main(), gcc 4.1.1
> says:
> "error: 'you' is not a member of 'Me'". If, instead, Me::you is
> *defined* at (1),
> then it compiles.
>
> MSVC++ Express compiles it either way without a problem, as expected.
>
> Surely this is a bug in gcc?
>


Why?

Declaring a function as a friend does not declare or define that function.
It merely states that said function is a friend.

In case (1), you're declaring *and* defining Me::you(). If you move that to
after main() as in case (2), then when main() is compiled, Me::you() has not
yet been declaredand so it's an error.

-Howard





 
Reply With Quote
 
 
 
 
JLS
Guest
Posts: n/a
 
      05-16-2007
On May 16, 11:38 am, (E-Mail Removed) wrote:
> Hello All,
>
> I am doing another exercise (I repeat, *exercise*). The (irrelevant to
> this
> discussion) point is to show that "You can inject a friend declaration
> into
> a namespace by declaring it within an enclosed class". I have done
> this
> successfully, but please consider the following program:
>
> //: C10:FriendInjection.cpp
> // From Thinking in C++, 2nd Edition
> // Available athttp://www.BruceEckel.com
> // (c) Bruce Eckel 2000
> // Copyright notice in Copyright.txt
> namespace Me {
> class Us {
> //...
> public:
> friend void you();
> };}
>
> // 1
> void Me::you(){}
>
> int main() {
> Me::you();
> return 0;
>
> }
>
> // 2
> // defining you() after main() does not compile
> // void Me::you(){}
> ///:~
> /////////////////////////////////////////////////////////////////////////
>
> If Me::you() is *defined* at (2) after the call in main(), gcc 4.1.1
> says:
> "error: 'you' is not a member of 'Me'". If, instead, Me::you is
> *defined* at (1),
> then it compiles.
>
> MSVC++ Express compiles it either way without a problem, as expected.
>
> Surely this is a bug in gcc?


What happens if you change it to

int main() {
Me::Us::you();
return 0;

I would have thought that the "Us" would be necessary.

 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      05-16-2007

"JLS" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> On May 16, 11:38 am, (E-Mail Removed) wrote:
>> Hello All,
>>
>> I am doing another exercise (I repeat, *exercise*). The (irrelevant to
>> this
>> discussion) point is to show that "You can inject a friend declaration
>> into
>> a namespace by declaring it within an enclosed class". I have done
>> this
>> successfully, but please consider the following program:
>>
>> //: C10:FriendInjection.cpp
>> // From Thinking in C++, 2nd Edition
>> // Available athttp://www.BruceEckel.com
>> // (c) Bruce Eckel 2000
>> // Copyright notice in Copyright.txt
>> namespace Me {
>> class Us {
>> //...
>> public:
>> friend void you();
>> };}
>>
>> // 1
>> void Me::you(){}
>>
>> int main() {
>> Me::you();
>> return 0;
>>
>> }
>>
>> // 2
>> // defining you() after main() does not compile
>> // void Me::you(){}
>> ///:~
>> /////////////////////////////////////////////////////////////////////////
>>
>> If Me::you() is *defined* at (2) after the call in main(), gcc 4.1.1
>> says:
>> "error: 'you' is not a member of 'Me'". If, instead, Me::you is
>> *defined* at (1),
>> then it compiles.
>>
>> MSVC++ Express compiles it either way without a problem, as expected.
>>
>> Surely this is a bug in gcc?

>
> What happens if you change it to
>
> int main() {
> Me::Us::you();
> return 0;
>
> I would have thought that the "Us" would be necessary.
>


Huh? The function you() is not a member of Us. It's a *friend* of Us.

-Howard



 
Reply With Quote
 
BigBrian
Guest
Posts: n/a
 
      05-16-2007
> Surely this is a bug in gcc?

gcc 4.0.1 compiles it either way for me.

 
Reply With Quote
 
johnbrown105@hotmail.com
Guest
Posts: n/a
 
      05-16-2007
On May 16, 11:16 am, "Howard" <(E-Mail Removed)> wrote:
> <(E-Mail Removed)> wrote in message
>
> Why?
>
> Declaring a function as a friend does not declare or define that function.
> It merely states that said function is a friend.
>
> In case (1), you're declaring *and* defining Me::you(). If you move that to
> after main() as in case (2), then when main() is compiled, Me::you() has not
> yet been declared and so it's an error.
>
> -Howard


Bruce Eckel has this to say in his book:

"Notice the two other friend functions. The first declares an ordinary
global function g( ) as a friend. But g( ) has not been previously
declared at the global scope! It turns out that friend can be used
this way to simultaneously declare the function *and* give it friend
status."

Of course, he could be wrong, but then again, so could you. I have not
read the standards myself, and I probably never will. Who agrees with
Bruce? With Howard?

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-16-2007
On May 16, 5:38 pm, (E-Mail Removed) wrote:

> I am doing another exercise (I repeat, *exercise*). The
> (irrelevant to this discussion) point is to show that "You can
> inject a friend declaration into a namespace by declaring it
> within an enclosed class".


This is not up to date. Originally, a name declared in a friend
declaration was injected into the enclosing namespace (or file
scope, as it was then). This was changed in the standard, and
friend names are no longer injected.

> I have done this successfully, but
> please consider the following program:


> //: C10:FriendInjection.cpp
> // From Thinking in C++, 2nd Edition
> // Available athttp://www.BruceEckel.com
> // (c) Bruce Eckel 2000
> // Copyright notice in Copyright.txt
> namespace Me {
> class Us {
> //...
> public:
> friend void you();
> };}


> // 1
> void Me::you(){}


> int main() {
> Me::you();
> return 0;
>
> }


This should not compile with an up-to-date compiler. Bruce
Eckel doubtlessly learned C++ before the change.

This would be legal according to the ARM, if you dropped the
namespace. I suspect that there were also many compilers which
supported it when they first introduced namespace as well.

> // 2
> // defining you() after main() does not compile
> // void Me::you(){}
> ///:~
> /////////////////////////////////////////////////////////////////////////


> If Me::you() is *defined* at (2) after the call in main(), gcc 4.1.1
> says:
> "error: 'you' is not a member of 'Me'". If, instead, Me::you is
> *defined* at (1),
> then it compiles.


> MSVC++ Express compiles it either way without a problem, as expected.


> Surely this is a bug in gcc?


I wouldn't call it a bug. Technically, g++ is correct,
according to the standard. MSV++ is correct, according to
pre-standard conventions.

In practice, it's hard to conceive of a real program where the
change makes a difference. The most typical use of the friend
function is for operator's, which have a parameter of the class
type, and in this case, ADL now picks up the name. (ADL wasn't
present in earlier C++.) FWIW: this change broke none of my
earlier C++ (although other changes did).

--
James Kanze (Gabi Software) email: http://www.velocityreviews.com/forums/(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
johnbrown105@hotmail.com
Guest
Posts: n/a
 
      05-16-2007
On May 16, 12:22 pm, BigBrian <(E-Mail Removed)> wrote:
> > Surely this is a bug in gcc?

>
> gcc 4.0.1 compiles it either way for me.


As does gcc-3.4.2, OpenWatcom 1.6 and DigitalMars 8.49. For what it's
worth, the Comeau compiler (with default options) at
http://www.comeaucomputing.com/tryitout/ likes neither (1) nor (2).

So Howard, does your compiler reject (2), as you say it should?

 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      05-16-2007

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> On May 16, 12:22 pm, BigBrian <(E-Mail Removed)> wrote:
>> > Surely this is a bug in gcc?

>>
>> gcc 4.0.1 compiles it either way for me.

>
> As does gcc-3.4.2, OpenWatcom 1.6 and DigitalMars 8.49. For what it's
> worth, the Comeau compiler (with default options) at
> http://www.comeaucomputing.com/tryitout/ likes neither (1) nor (2).
>
> So Howard, does your compiler reject (2), as you say it should?
>


Nope. VC++ (from Visual Studio 2003) accepts it either way. But the
question is what does the standard say, not what does Microsoft (or any
other vendor) say. I don't have the standard handy (and I have a great deal
of trouble understanding its legalese style), but I think James Kanze's
answer covers it pretty well.

-Howard



 
Reply With Quote
 
johnbrown105@hotmail.com
Guest
Posts: n/a
 
      05-17-2007
On May 16, 3:39 pm, James Kanze <(E-Mail Removed)> wrote:
> On May 16, 5:38 pm, (E-Mail Removed) wrote:
>
> > I am doing another exercise (I repeat, *exercise*). The
> > (irrelevant to this discussion) point is to show that "You can
> > inject a friend declaration into a namespace by declaring it
> > within an enclosed class".

>
> This is not up to date. Originally, a name declared in a friend
> declaration was injected into the enclosing namespace (or file
> scope, as it was then). This was changed in the standard, and
> friend names are no longer injected.
>


I see. Well, the book is old ((c) 2000) and the compilers mentioned in
my later post are also old (mostly).
>
><cut>
>
> I wouldn't call it a bug. Technically, g++ is correct,
> according to the standard. MSV++ is correct, according to
> pre-standard conventions.
>

<cut>
The most typical use of the friend
> function is for operator's, which have a parameter of the class
> type, and in this case, ADL now picks up the name. (ADL wasn't
> present in earlier C++.)


Is this "ADL" why the mighty Comeau compiler accepts neither (1) nor
(2)?

 
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
function declared, but not defined Tagore C Programming 7 07-26-2010 09:27 AM
Function call after switch but before first case - behavior? yndygo@gmail.com C++ 9 05-02-2007 10:44 PM
defined? for recursive function call v/s defined? for function call stack Alok Ruby 3 04-13-2006 11:53 AM
declared or not declared ? JohnZing ASP .Net 3 02-05-2006 08:38 PM
#if (defined(__STDC__) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) Oodini C Programming 1 09-27-2005 07:58 PM



Advertisments