public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: C++ 'extern inline' magic possible?
       [not found] <4D6C35D1.4080104@digium.com>
@ 2011-03-01  0:25 ` Ian Lance Taylor
  2011-03-01  1:10   ` Jonathan Wakely
  2011-03-01  1:07 ` Jonathan Wakely
  1 sibling, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2011-03-01  0:25 UTC (permalink / raw)
  To: Kevin P. Fleming; +Cc: gcc-help

"Kevin P. Fleming" <kpfleming@digium.com> writes:

> I would like to come up with some construction like the 'extern
> inline' that GCC supports for C mode, so that a.h could contain the
> declaration *and* definition of 'bar', allowing code that includes a.h
> to have 'bar' be inlined if the compiler chooses to do so (and leave
> an external reference to 'bar' if necessary so that the version built
> from a.cpp will be used). So far my attempts have only resulted in
> various re-definition or re-declaration errors.

There is no equivalent to GNU C's "extern inline" in C++.  By the way,
"extern inline" is now actually known as __attribute__ ((gnu_inline)),
as C99 defines "extern inline" to mean something different.

In C++ you can simply define the function inline in a.h, and not define
it at all in a.cpp.  The right thing will happen.

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
       [not found] <4D6C35D1.4080104@digium.com>
  2011-03-01  0:25 ` C++ 'extern inline' magic possible? Ian Lance Taylor
@ 2011-03-01  1:07 ` Jonathan Wakely
  1 sibling, 0 replies; 13+ messages in thread
From: Jonathan Wakely @ 2011-03-01  1:07 UTC (permalink / raw)
  To: Kevin P. Fleming; +Cc: gcc-help

On 28 February 2011 23:54, Kevin P. Fleming wrote:
> In a C++ application consisting of a large number of source files, I've got
> a situation where there is a non-member function that *some* users could
> inline (because they can see the definition of the classes involved in the
> function's parameters and return value) and other users cannot inline
> (because they are only know of those classes due to forward declarations,
> and the function accepts and returns pointers to objects).
>
> As it stands right now, the header file declares this function for all
> callers, and there is one source file that provides the definition; this
> works, because all callers call the function after the library that provides
> the function is dynamically linked into their process.
>
> The function, though, is terribly simple, and the function call overhead
> easily dwarfs the code the function actually runs (in one case, the function
> is nothing more than a wrapper for the equivalent of a static_cast<>). If
> the compiler could see the function body it would be able to inline it in a
> large number of cases, reducing code size and improving performance.
>
> I have three source files involved here:
>
> aF.h contains only a forward declaration of class Foo, and a declaration of
> 'void bar(const Foo *)'.
>
> a.h contains the declaration and definition of class Foo, and a declaration
> of 'void bar(const Foo *)'.
>
> a.cpp contains the definition of 'void bar(const Foo *)'.
>
> I would like to come up with some construction like the 'extern inline' that
> GCC supports for C mode, so that a.h could contain the declaration *and*
> definition of 'bar', allowing code that includes a.h to have 'bar' be
> inlined if the compiler chooses to do so (and leave an external reference to
> 'bar' if necessary so that the version built from a.cpp will be used). So
> far my attempts have only resulted in various re-definition or
> re-declaration errors.
>
> Is there a way to do this in C++ mode? I see lots of pages with useful
> details and example for C mode, but not for C++ mode. I am *not* specifying
> '-std' to the compiler at all, and am using GCC 4.4; I've tried using
> '-std=c99' but that doesn't seem to do what I want (with the definition in
> the header marked 'inline' and the definition in the source file marked
> 'extern inline').

-std=c99 says which dialect to use when compiling C, it doesn't do
anything when compiling C++

The C++ standard says an extern function declared inline must be
declared inline in all translation units where it appears, and that a
definition of an inline function must appear in every translation unit
that uses it.  That is quite different to the C99 concept of an
"inline definition" which can exist in addition to an alternative
extern definition.

I would define two functions with different names, one inline and one
not. The non-inline function could include the definition of the
inline function and call it, so there is no more overhead.  That's
probably not what you want though, as you need to call a different
name depending on whether the inline function is available or not.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01  0:25 ` C++ 'extern inline' magic possible? Ian Lance Taylor
@ 2011-03-01  1:10   ` Jonathan Wakely
  2011-03-01  3:54     ` Ian Lance Taylor
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Wakely @ 2011-03-01  1:10 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Kevin P. Fleming, gcc-help

On 1 March 2011 00:25, Ian Lance Taylor  wrote:
> "Kevin P. Fleming" <kpfleming@digium.com> writes:
>
>> I would like to come up with some construction like the 'extern
>> inline' that GCC supports for C mode, so that a.h could contain the
>> declaration *and* definition of 'bar', allowing code that includes a.h
>> to have 'bar' be inlined if the compiler chooses to do so (and leave
>> an external reference to 'bar' if necessary so that the version built
>> from a.cpp will be used). So far my attempts have only resulted in
>> various re-definition or re-declaration errors.
>
> There is no equivalent to GNU C's "extern inline" in C++.  By the way,
> "extern inline" is now actually known as __attribute__ ((gnu_inline)),
> as C99 defines "extern inline" to mean something different.
>
> In C++ you can simply define the function inline in a.h, and not define
> it at all in a.cpp.  The right thing will happen.

That will work in practice, but it's technically an ODR violation.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01  1:10   ` Jonathan Wakely
@ 2011-03-01  3:54     ` Ian Lance Taylor
  2011-03-01  8:55       ` Jonathan Wakely
  0 siblings, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2011-03-01  3:54 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Kevin P. Fleming, gcc-help

Jonathan Wakely <jwakely.gcc@gmail.com> writes:

> On 1 March 2011 00:25, Ian Lance Taylor  wrote:
>> "Kevin P. Fleming" <kpfleming@digium.com> writes:
>>
>>> I would like to come up with some construction like the 'extern
>>> inline' that GCC supports for C mode, so that a.h could contain the
>>> declaration *and* definition of 'bar', allowing code that includes a.h
>>> to have 'bar' be inlined if the compiler chooses to do so (and leave
>>> an external reference to 'bar' if necessary so that the version built
>>> from a.cpp will be used). So far my attempts have only resulted in
>>> various re-definition or re-declaration errors.
>>
>> There is no equivalent to GNU C's "extern inline" in C++.  By the way,
>> "extern inline" is now actually known as __attribute__ ((gnu_inline)),
>> as C99 defines "extern inline" to mean something different.
>>
>> In C++ you can simply define the function inline in a.h, and not define
>> it at all in a.cpp.  The right thing will happen.
>
> That will work in practice, but it's technically an ODR violation.

No, it's not (there may be a misunderstanding somewhere).  I am
suggesting that there should be only one definition: the one in a.h.
That is OK if the definition has inline linkage.  It is certainly not an
ODR violation, as there is only one definition.

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01  3:54     ` Ian Lance Taylor
@ 2011-03-01  8:55       ` Jonathan Wakely
  2011-03-01 12:14         ` Kevin P. Fleming
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Wakely @ 2011-03-01  8:55 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Kevin P. Fleming, gcc-help

On 1 March 2011 03:53, Ian Lance Taylor wrote:
> Jonathan Wakely <jwakely.gcc@gmail.com> writes:
>
>> On 1 March 2011 00:25, Ian Lance Taylor  wrote:
>>> "Kevin P. Fleming" <kpfleming@digium.com> writes:
>>>
>>>> I would like to come up with some construction like the 'extern
>>>> inline' that GCC supports for C mode, so that a.h could contain the
>>>> declaration *and* definition of 'bar', allowing code that includes a.h
>>>> to have 'bar' be inlined if the compiler chooses to do so (and leave
>>>> an external reference to 'bar' if necessary so that the version built
>>>> from a.cpp will be used). So far my attempts have only resulted in
>>>> various re-definition or re-declaration errors.
>>>
>>> There is no equivalent to GNU C's "extern inline" in C++.  By the way,
>>> "extern inline" is now actually known as __attribute__ ((gnu_inline)),
>>> as C99 defines "extern inline" to mean something different.
>>>
>>> In C++ you can simply define the function inline in a.h, and not define
>>> it at all in a.cpp.  The right thing will happen.
>>
>> That will work in practice, but it's technically an ODR violation.
>
> No, it's not (there may be a misunderstanding somewhere).  I am
> suggesting that there should be only one definition: the one in a.h.
> That is OK if the definition has inline linkage.  It is certainly not an
> ODR violation, as there is only one definition.

Yes sorry, I did misunderstand.  But in that case a.h must be included
by all callers of the function.  I thought the point was some callers
don't want to include the definition of the class and the function
that uses it.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01  8:55       ` Jonathan Wakely
@ 2011-03-01 12:14         ` Kevin P. Fleming
  2011-03-01 12:39           ` Andrew Haley
                             ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Kevin P. Fleming @ 2011-03-01 12:14 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Ian Lance Taylor, gcc-help

On 03/01/2011 02:55 AM, Jonathan Wakely wrote:
> On 1 March 2011 03:53, Ian Lance Taylor wrote:
>> Jonathan Wakely<jwakely.gcc@gmail.com>  writes:
>>
>>> On 1 March 2011 00:25, Ian Lance Taylor  wrote:
>>>> "Kevin P. Fleming"<kpfleming@digium.com>  writes:
>>>>
>>>>> I would like to come up with some construction like the 'extern
>>>>> inline' that GCC supports for C mode, so that a.h could contain the
>>>>> declaration *and* definition of 'bar', allowing code that includes a.h
>>>>> to have 'bar' be inlined if the compiler chooses to do so (and leave
>>>>> an external reference to 'bar' if necessary so that the version built
>>>>> from a.cpp will be used). So far my attempts have only resulted in
>>>>> various re-definition or re-declaration errors.
>>>>
>>>> There is no equivalent to GNU C's "extern inline" in C++.  By the way,
>>>> "extern inline" is now actually known as __attribute__ ((gnu_inline)),
>>>> as C99 defines "extern inline" to mean something different.
>>>>
>>>> In C++ you can simply define the function inline in a.h, and not define
>>>> it at all in a.cpp.  The right thing will happen.
>>>
>>> That will work in practice, but it's technically an ODR violation.
>>
>> No, it's not (there may be a misunderstanding somewhere).  I am
>> suggesting that there should be only one definition: the one in a.h.
>> That is OK if the definition has inline linkage.  It is certainly not an
>> ODR violation, as there is only one definition.
>
> Yes sorry, I did misunderstand.  But in that case a.h must be included
> by all callers of the function.  I thought the point was some callers
> don't want to include the definition of the class and the function
> that uses it.

Yes, that was what my original post requested, but I now understand that 
any solution that offered that would be non-compliant with the C++ 
standard. I believe this code base is only using this technique to shave 
some compile time for TUs that don't actually need the class definitions 
(they only receive and send around pointers to the classes), but it's a 
cause of lower performance and so I'll have to figure out whether 
removing the 'forward declaration only' mechanism will be worth the effort.

Thanks for the replies; as usual the level of knowledge and helpfulness 
on this mailing list is stellar :-)

On a slightly related note... I've seen a couple of pages (but not the 
GCC manual's 'inlining' page) mention that it's possible for virtual 
member functions to be inlined if they are inlinable (either defined in 
the class declaration or the function declaration is visible and marked 
'inline') and the call to them is a 'direct virtual function call'. This 
last term doesn't make any sense to me, and based on my understanding of 
vtables I don't see how a virtual member function could *ever* be 
inlined unless it was called in a non-virtual fashion (i.e. calling it 
as "Foo::bar()" when Foo is the class making the call or one of its 
bases). In any other situation, the compiler cannot know at compile time 
which member function would actually be called. Does this sound like a 
correct statement?

-- 
Kevin P. Fleming
Digium, Inc. | Director of Software Technologies
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
skype: kpfleming | jabber: kfleming@digium.com
Check us out at www.digium.com & www.asterisk.org

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01 12:14         ` Kevin P. Fleming
@ 2011-03-01 12:39           ` Andrew Haley
  2011-03-01 12:55           ` David Brown
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 13+ messages in thread
From: Andrew Haley @ 2011-03-01 12:39 UTC (permalink / raw)
  To: gcc-help

On 03/01/2011 12:14 PM, Kevin P. Fleming wrote:

> On a slightly related note... I've seen a couple of pages (but not the 
> GCC manual's 'inlining' page) mention that it's possible for virtual 
> member functions to be inlined if they are inlinable (either defined in 
> the class declaration or the function declaration is visible and marked 
> 'inline') and the call to them is a 'direct virtual function call'. This 
> last term doesn't make any sense to me, and based on my understanding of 
> vtables I don't see how a virtual member function could *ever* be 
> inlined unless it was called in a non-virtual fashion (i.e. calling it 
> as "Foo::bar()" when Foo is the class making the call or one of its 
> bases). In any other situation, the compiler cannot know at compile time 
> which member function would actually be called. Does this sound like a 
> correct statement?

Consider

   new Foo()->bar();

Andrew.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01 12:14         ` Kevin P. Fleming
  2011-03-01 12:39           ` Andrew Haley
@ 2011-03-01 12:55           ` David Brown
  2011-03-02 12:35             ` Kevin P. Fleming
  2011-03-01 15:39           ` Ian Lance Taylor
  2011-03-01 21:52           ` Jonathan Wakely
  3 siblings, 1 reply; 13+ messages in thread
From: David Brown @ 2011-03-01 12:55 UTC (permalink / raw)
  To: gcc-help

On 01/03/2011 13:14, Kevin P. Fleming wrote:
> On 03/01/2011 02:55 AM, Jonathan Wakely wrote:
>> On 1 March 2011 03:53, Ian Lance Taylor wrote:
>>> Jonathan Wakely<jwakely.gcc@gmail.com> writes:
>>>
>>>> On 1 March 2011 00:25, Ian Lance Taylor wrote:
>>>>> "Kevin P. Fleming"<kpfleming@digium.com> writes:
>>>>>
>>>>>> I would like to come up with some construction like the 'extern
>>>>>> inline' that GCC supports for C mode, so that a.h could contain the
>>>>>> declaration *and* definition of 'bar', allowing code that includes
>>>>>> a.h
>>>>>> to have 'bar' be inlined if the compiler chooses to do so (and leave
>>>>>> an external reference to 'bar' if necessary so that the version built
>>>>>> from a.cpp will be used). So far my attempts have only resulted in
>>>>>> various re-definition or re-declaration errors.
>>>>>
>>>>> There is no equivalent to GNU C's "extern inline" in C++. By the way,
>>>>> "extern inline" is now actually known as __attribute__ ((gnu_inline)),
>>>>> as C99 defines "extern inline" to mean something different.
>>>>>
>>>>> In C++ you can simply define the function inline in a.h, and not
>>>>> define
>>>>> it at all in a.cpp. The right thing will happen.
>>>>
>>>> That will work in practice, but it's technically an ODR violation.
>>>
>>> No, it's not (there may be a misunderstanding somewhere). I am
>>> suggesting that there should be only one definition: the one in a.h.
>>> That is OK if the definition has inline linkage. It is certainly not an
>>> ODR violation, as there is only one definition.
>>
>> Yes sorry, I did misunderstand. But in that case a.h must be included
>> by all callers of the function. I thought the point was some callers
>> don't want to include the definition of the class and the function
>> that uses it.
>
> Yes, that was what my original post requested, but I now understand that
> any solution that offered that would be non-compliant with the C++
> standard. I believe this code base is only using this technique to shave
> some compile time for TUs that don't actually need the class definitions
> (they only receive and send around pointers to the classes), but it's a
> cause of lower performance and so I'll have to figure out whether
> removing the 'forward declaration only' mechanism will be worth the effort.
>
> Thanks for the replies; as usual the level of knowledge and helpfulness
> on this mailing list is stellar :-)
>
> On a slightly related note... I've seen a couple of pages (but not the
> GCC manual's 'inlining' page) mention that it's possible for virtual
> member functions to be inlined if they are inlinable (either defined in
> the class declaration or the function declaration is visible and marked
> 'inline') and the call to them is a 'direct virtual function call'. This
> last term doesn't make any sense to me, and based on my understanding of
> vtables I don't see how a virtual member function could *ever* be
> inlined unless it was called in a non-virtual fashion (i.e. calling it
> as "Foo::bar()" when Foo is the class making the call or one of its
> bases). In any other situation, the compiler cannot know at compile time
> which member function would actually be called. Does this sound like a
> correct statement?
>

The compiler is free to inline functions as part of its optimisations. 
To do that, it needs to be sure what functions to call, and to have 
access to the definition of the function.  Marking a function "inline" 
is a hint that you'd like inlining, but the compiler may not be able to 
inline a function marked "inline", and it may also choose to inline 
functions that are not marked.

This will apply equally to virtual methods.  If the compiler can be sure 
of which function is actually being called with the virtual method call, 
it can remove the indirection and call the underlying function directly, 
or inline it.

If you want the compiler to inline functions where practical, even 
across different compilation units, and to use function calls when 
necessary, then you should look hard at using LTO.  This gives the 
compiler the chance to inline function calls even though the definitions 
are not available in the compilation unit in which they are used.




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01 12:14         ` Kevin P. Fleming
  2011-03-01 12:39           ` Andrew Haley
  2011-03-01 12:55           ` David Brown
@ 2011-03-01 15:39           ` Ian Lance Taylor
  2011-03-01 21:52           ` Jonathan Wakely
  3 siblings, 0 replies; 13+ messages in thread
From: Ian Lance Taylor @ 2011-03-01 15:39 UTC (permalink / raw)
  To: Kevin P. Fleming; +Cc: Jonathan Wakely, gcc-help

"Kevin P. Fleming" <kpfleming@digium.com> writes:

> On a slightly related note... I've seen a couple of pages (but not the
> GCC manual's 'inlining' page) mention that it's possible for virtual
> member functions to be inlined if they are inlinable (either defined
> in the class declaration or the function declaration is visible and
> marked 'inline') and the call to them is a 'direct virtual function
> call'. This last term doesn't make any sense to me, and based on my
> understanding of vtables I don't see how a virtual member function
> could *ever* be inlined unless it was called in a non-virtual fashion
> (i.e. calling it as "Foo::bar()" when Foo is the class making the call
> or one of its bases). In any other situation, the compiler cannot know
> at compile time which member function would actually be called. Does
> this sound like a correct statement?

The direct virtual function call is indeed the call to Foo::bar().

However, there are other cases where the compiler can inline a virtual
function call.  If the compiler can see the use of the new operator
which created the object, then it knows the exact virtual table which
the object is using, and so can inline any virtual call.  That is a
fairly common though obviously somewhat limited case.  In gcc these
sorts of optimizations are implemented by -fdevirtualize, which is
enabled by default at -O2.

More subtly, the compiler can use profiling feedback to see which
virtual function is being called at any specific point in the code.  In
many programs a specific call site will almost always call a specific
virtual function implementation.  When the profiling feedback indicates
that, the compiler can insert a test for the expected virtual function.
If the test succeeds, the compiler can inline the call.  If the test
fails, the compiler can generate a normal virtual function call.  I
don't know off-hand whether gcc implements this optimization.

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01 12:14         ` Kevin P. Fleming
                             ` (2 preceding siblings ...)
  2011-03-01 15:39           ` Ian Lance Taylor
@ 2011-03-01 21:52           ` Jonathan Wakely
  2011-03-02 13:00             ` Kevin P. Fleming
  3 siblings, 1 reply; 13+ messages in thread
From: Jonathan Wakely @ 2011-03-01 21:52 UTC (permalink / raw)
  To: Kevin P. Fleming; +Cc: gcc-help

On 1 March 2011 12:14, Kevin P. Fleming wrote:
>
> Yes, that was what my original post requested, but I now understand that any
> solution that offered that would be non-compliant with the C++ standard. I
> believe this code base is only using this technique to shave some compile
> time for TUs that don't actually need the class definitions (they only
> receive and send around pointers to the classes), but it's a cause of lower
> performance and so I'll have to figure out whether removing the 'forward
> declaration only' mechanism will be worth the effort.

There is another option, which I'm loathe to mention ...

// aF.h

class Foo;
void bar_ext(const Foo*);
#ifndef BAR_INLINED
#define BAR bar_ext
#endif

// a.h

class Foo { };
void bar_inl(const Foo*) { }
#undef BAR
#define BAR bar_inl
#define BAR_INLINED

this way you call BAR() and get the inline bar_inl if its definition
has been seen, or bar_ext otherwise.

But macros introduce their own problems so use with caution.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01 12:55           ` David Brown
@ 2011-03-02 12:35             ` Kevin P. Fleming
  0 siblings, 0 replies; 13+ messages in thread
From: Kevin P. Fleming @ 2011-03-02 12:35 UTC (permalink / raw)
  To: gcc-help

On 03/01/2011 07:53 AM, David Brown wrote:

> If you want the compiler to inline functions where practical, even
> across different compilation units, and to use function calls when
> necessary, then you should look hard at using LTO. This gives the
> compiler the chance to inline function calls even though the definitions
> are not available in the compilation unit in which they are used.

That is on my agenda as well to investigate, but since GCC+binutils that 
support LTO are very, very new and won't be in LTS-type Linux 
distributions for some time, we can't quite expect our users to have 
them available.

-- 
Kevin P. Fleming
Digium, Inc. | Director of Software Technologies
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
skype: kpfleming | jabber: kfleming@digium.com
Check us out at www.digium.com & www.asterisk.org

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-01 21:52           ` Jonathan Wakely
@ 2011-03-02 13:00             ` Kevin P. Fleming
  2011-03-02 16:55               ` Jonathan Wakely
  0 siblings, 1 reply; 13+ messages in thread
From: Kevin P. Fleming @ 2011-03-02 13:00 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On 03/01/2011 04:52 PM, Jonathan Wakely wrote:
> On 1 March 2011 12:14, Kevin P. Fleming wrote:
>>
>> Yes, that was what my original post requested, but I now understand that any
>> solution that offered that would be non-compliant with the C++ standard. I
>> believe this code base is only using this technique to shave some compile
>> time for TUs that don't actually need the class definitions (they only
>> receive and send around pointers to the classes), but it's a cause of lower
>> performance and so I'll have to figure out whether removing the 'forward
>> declaration only' mechanism will be worth the effort.
>
> There is another option, which I'm loathe to mention ...

<snip macro example which makes everyone shudder <G>>

Yes, I considered that. I did arrive at a potential solution, although I 
can't use it in this particular code base because of other 
complications, but...

== test.h ==
class Foo;

void opaqueBar(Foo*);

template <typename T>
void Bar(T* obj)
{
	opaqueBar(obj);
}

== test1.h ==
#include "test.h"

static void test1(Foo* obj)
{
	Bar(obj);
}

== test2.h ==
#include "test.h"

class Foo
{
public:
	void realBar();
};

template <>
inline void Bar<Foo>(Foo* obj)
{
	obj->realBar();
}

static void test2(Foo* obj)
{
	Bar(obj);
}

I think this still might be an ODR violation though, since there will 
end up being two definitions of Bar() for Foo.

-- 
Kevin P. Fleming
Digium, Inc. | Director of Software Technologies
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
skype: kpfleming | jabber: kfleming@digium.com
Check us out at www.digium.com & www.asterisk.org

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: C++ 'extern inline' magic possible?
  2011-03-02 13:00             ` Kevin P. Fleming
@ 2011-03-02 16:55               ` Jonathan Wakely
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Wakely @ 2011-03-02 16:55 UTC (permalink / raw)
  To: Kevin P. Fleming; +Cc: gcc-help

On 2 March 2011 13:00, Kevin P. Fleming wrote:
> On 03/01/2011 04:52 PM, Jonathan Wakely wrote:
>>
>> On 1 March 2011 12:14, Kevin P. Fleming wrote:
>>>
>>> Yes, that was what my original post requested, but I now understand that
>>> any
>>> solution that offered that would be non-compliant with the C++ standard.
>>> I
>>> believe this code base is only using this technique to shave some compile
>>> time for TUs that don't actually need the class definitions (they only
>>> receive and send around pointers to the classes), but it's a cause of
>>> lower
>>> performance and so I'll have to figure out whether removing the 'forward
>>> declaration only' mechanism will be worth the effort.
>>
>> There is another option, which I'm loathe to mention ...
>
> <snip macro example which makes everyone shudder <G>>
>
> Yes, I considered that. I did arrive at a potential solution, although I
> can't use it in this particular code base because of other complications,
> but...
>
> == test.h ==
> class Foo;
>
> void opaqueBar(Foo*);
>
> template <typename T>
> void Bar(T* obj)
> {
>        opaqueBar(obj);
> }
>
> == test1.h ==
> #include "test.h"
>
> static void test1(Foo* obj)
> {
>        Bar(obj);
> }
>
> == test2.h ==
> #include "test.h"
>
> class Foo
> {
> public:
>        void realBar();
> };
>
> template <>
> inline void Bar<Foo>(Foo* obj)
>
> {
>        obj->realBar();
> }
>
> static void test2(Foo* obj)
> {
>        Bar(obj);
> }
>
> I think this still might be an ODR violation though, since there will end up
> being two definitions of Bar() for Foo.

Yep:

[templ.expl.spec]p6:
If a template, a member template or the member of a class template is
explicitly specialized then that
specialization shall be declared before the first use of that
specialization that would cause an implicit instantiation
to take place, in every translation unit in which such a use occurs;
no diagnostic is required.


The answer is to overload Bar as a non-template, not to specialize the
template function.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-03-02 16:55 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <4D6C35D1.4080104@digium.com>
2011-03-01  0:25 ` C++ 'extern inline' magic possible? Ian Lance Taylor
2011-03-01  1:10   ` Jonathan Wakely
2011-03-01  3:54     ` Ian Lance Taylor
2011-03-01  8:55       ` Jonathan Wakely
2011-03-01 12:14         ` Kevin P. Fleming
2011-03-01 12:39           ` Andrew Haley
2011-03-01 12:55           ` David Brown
2011-03-02 12:35             ` Kevin P. Fleming
2011-03-01 15:39           ` Ian Lance Taylor
2011-03-01 21:52           ` Jonathan Wakely
2011-03-02 13:00             ` Kevin P. Fleming
2011-03-02 16:55               ` Jonathan Wakely
2011-03-01  1:07 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).