Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
783 views
in Technique[技术] by (71.8m points)

templates - Why C++ linker is silent about ODR violation?

Let's consider some synthetic but expressive example. Suppose we have Header.h:

Header1.h

#include <iostream>

// Define generic version
template<typename T>
inline void Foo()
{
    std::cout << "Generic
";
}

Header2.h

void Function1();

Header3.h

void Function2();

Source1.cpp

#include "Header1.h"
#include "Header3.h"

// Define specialization 1
template<>
inline void Foo<int>()
{
    std::cout << "Specialization 1
";
}

void Function1()
{
    Foo<int>();
}

Later I or some else defines similar conversion in another source file. Source2.cpp

#include "Header1.h"

// Define specialization 2
template<>
inline void Foo<int>()
{
    std::cout << "Specialization 2
";
}

void Function2()
{
    Foo<int>();
}

main.cpp

#include "Header2.h"
#include "Header3.h"

int main()
{
    Function1();
    Function2();
}

The question is what will print Function1() and Function2()? The answer is undefined behavior.

I expect to see in output: Specialization 1 Specialization 2

But I see: Specialization 2 Specialization 2

Why C++ compilers are silent about ODR violation? I would prefer compilation to be failed in this case.

I found only one workaround: define template functions in unnamed namespace.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The compiler is silent, because it's not required to emit anything by [basic.def.odr/4]:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...