Legal C++?

Started by
6 comments, last by phresnel 14 years, 1 month ago
I was playing around and found that:

struct Test {
   void f1 () { f2(); }
   void f2 () { cout << "Test::f2()" << endl; }
   };

Compiles and runs find in VC++ express (2010 beta version). I was under the impression that it should not compile (f2 should be undefined for f1). Is the above legal C++?
Advertisement
Member functions are defined as part of interface, and they are all known in advance. Placement of bodies is merely another way to hint or demand inline.

In C, functions are parsed top-to-bottom, and even that might not hold for recent revisions. Hence the need for forward declarations.

The parsed equivalent is this:
struct Test {   void f1 ();   void f2 ();   };void Test::f1 () { f2(); }void Test::f2 () { cout << "Test::f2()" << endl; }


IIRC, standard might disagree.
The relevant part of the standard seems to be section 9.2 paragraph 2 which states that inside function definitions inside the class definition the complete type of the class is used.
Quote:Original post by no such user
The relevant part of the standard seems to be section 9.2 paragraph 2 which states that inside function definitions inside the class definition the complete type of the class is used.


Thank-you, that's good to know.

I thought C++ was designed so at least (in theory) it was possible to parse in a single pass. At the very least that would require the caching of the function bodies till after.
Code marked inline (either with the keyword or placing the body with the declaration) is given internal linkage, meaning you're allowed to provide the body in every translation unit, and in fact have to do so. I wonder if people ever use the inline keyword to gain that behavior instead of for the optimisation, which the compiler will probably ignore anyway!
Yes, technically people do that all the time, although you might not realize it. Template functions are the really obvious example. In theory you can explicitly instantiate them in a single translation unit, but almost no one does that. Most people just put all their template code into headers, even when the function bodies are much larger and more complex than any compiler's inlining threshold.
A while back I was writing some template code that ended up calling a function which was part of the process, but not itself a template. The compiler was giving "symbol already defined" errors on the non-template function. My code looked something like this:

// Utils.hnamespace Utils{	template<class T>	int doSomething(T param);	int doSomethingHelper(int param);}// Begin definitionstemplate<class T>int Utils::doSomething(T param){	...}int Utils::doSomethingHelper(int param){	...}


I solved it by moving doSomethingHelper out to it's own cpp file, but I suppose I could have marked it inline to give it internal linkage like the template functions have.
Quote:Original post by taz0010
A while back I was writing some template code that ended up calling a function which was part of the process, but not itself a template. The compiler was giving "symbol already defined" errors on the non-template function. My code looked something like this:

// Utils.hnamespace Utils{	template<class T>	int doSomething(T param);	int doSomethingHelper(int param);}// Begin definitionstemplate<class T>int Utils::doSomething(T param){	...}int Utils::doSomethingHelper(int param){	...}


I solved it by moving doSomethingHelper out to it's own cpp file, but I suppose I could have marked it inline to give it internal linkage like the template functions have.


Yes, because you haven't stated in the code that doSomethingHelper() has internal linkage. So yes, the solution is to either make it inline, or to move it to a cc-file.

And if your intention is to make a template inline (member) function, then you should also mark that as inline or define it inside the class.

This topic is closed to new replies.

Advertisement