Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My template specialization differs debug version from release version, is this gcc bug?

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:

  1. Is "weak symbol"/"strong symbol" a concept of gcc/g++, or it's part of the c/c++ language specification.

  2. 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?

like image 913
Troskyvs Avatar asked Dec 25 '22 00:12

Troskyvs


1 Answers

The language definition requires that you declare an explicit specialization before it is used:

If a template, a member template or a 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. [temp.expl.spec]/6.

There is no declaration of the explicit specialization of foo<float>::init() at the point where it is called from main, but there is an explicit specialization in foo_float.cpp, so the behavior of the program is undefined.

like image 101
Pete Becker Avatar answered Dec 26 '22 13:12

Pete Becker