First of all, I've got a header file for a class, an specialization declaration without definition(code samples from internet)
$ cat foo.h
template<typename T>
class foo{
public:
static void init(){
return;
}
};
template<> void foo<int>::init();
Then there're 2 implementation files for template specialization
$ cat foo_int.cpp
#include "foo.h"
#include<stdio.h>
template<>
void foo<int>::init(){
printf("init int foo\n");
}
$ cat foo_float.cpp
#include "foo.h"
#include<stdio.h>
template<>
void foo<float>::init(){
printf("init float foo\n");
}
Finally I got a main file
$ cat main.cpp
#include "foo.h"
int main(){
foo<int>::init();
foo<float>::init();
}
If I compile it without optimization and run it, it gives:
g++ foo_int.cpp foo_float.cpp main.cpp && a.out
init int foo
init float foo
If I add optimization, then the result is different:
$ g++ foo_int.cpp foo_float.cpp main.cpp -O2 && a.out
init int foo
The result is different. Some explanation from internet said this is due to some internal mechanism of "weak symbol" in gcc implementation, but my question:
Is "weak symbol"/"strong symbol" a concept of gcc/g++, or it's part of the c/c++ language specification.
If debug and release results are different, should I say this is a bug/issue of gcc/g++, in regard with "weak symbol" mechanism? As a developer, I wouldn't expect my debug version to behave differently from release version.
I tried clang, unfortunately same error. Is this an "acceptable" case for C/C++ that debug/release "should" behave so differently?
You've violated the one definition rule — your program contains two definitions of foo<float>::init
.
One definition occurs in the compilation unit foo_float.cpp
, and the other appears in the compilation unit main.cpp
.
Violating the one definition rule means undefined behavior — in this case, what likely happens is:
foo_float.cpp
's version of the function in the executable.main.cpp
the compiler inlined the function — naturally, it would inline main.cpp
's version of the function.