This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: One-definition rule for inline functions


On 08.03.2012 03:11, Jonathan Wakely wrote:
On 8 March 2012 01:10, Jonathan Wakely wrote:
On 8 March 2012 01:02, Timothy Madden wrote:
Hello

I have an inline function like this:

void draw_unit_vector()
{
        // some large code here
        // ...

        LineTo(1, 1);
}

in two translation units A and B.

Now if the function is large enough it is still compiled and called, and not
inlined.

The LineTo() function has two overloads:
        - translation unit A only needs the float version:
                  LineTo(float x, float y);
          and declares it before it includes the inline function.
        - translation unit B uses both int and float versions:
                  LineTo(int x, int y);
                  LineTo(float x, float y);
          and declares them before it includes the inline function.

The same inline function would call LineTo(float, float) in source A, but
would call LineTo(int, int) in source B. And it so happens that the two
overloads for LineTo() are quite different, the int version is for text-mode
only, while the float version is for graphics mode.

By the C++ standard this case is a clear violation of the one-definition
rule, and users should take good care to avoid it.

My question is: what does g++ do in such case ?

Does it compile two different draw_unit_vector() functions from the same
inline function definition ?

Yes, then discards one of the definitions, see http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html

Or more precisely, the linker discards one of them.


Thank you.

Now say I have a function template (which is not declared with "inline" but is inlined nonetheless by its nature):

template<typename T>
    void draw_unit_vector()
    {
        T x(1), y(1);

        // ... some code
        LineTo(x, y);
    };

Now translation unit A includes the template and than says:

extern void LineTo(float x, float y);

draw_unit_vector<int>();

and than translation unit B in the same program includes the template and than says:

extern void LineTo(int x, int y);
extern void LineTO(float x, float y);

draw_unit_vector<int>();


In this case again, the same instantiation, namely draw_unit_vector<int> (only this time from a template, not from an inline function) compiles to two different functions.


In source A the instantiation invokes the float LineTo, in source B the same instantiation invokex the int LineTo.

What does g++ do with this template ?
Does it really compile any templates in each and every .cc file that they are used in ?


Thank you,
Timothy Madden


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]