vendredi 29 juin 2018

Variadic templates have duplicate symbols in object files?

I have the following test program:

#include <cstdio>

template<int i, int j, int k>
struct Dispatcher {
  template<typename... F>
  static inline void call1(bool a, bool b, int* output, F...) {
    *output = i;
    if (a) *output += j;
    if (b) *output += k;
  }

  template<typename F>
  static inline void call2(bool a, bool b, int* output, F) {
    *output = i;
    if (a) *output += j;
    if (b) *output += k;
  }
};


int main() {
  int output;
  Dispatcher<1, 2, 3>::call1(true, false, &output, 1337);
  printf("%i\n", output);
  Dispatcher<1, 2, 3>::call2(true, false, &output, 1337);
  printf("%i\n", output);
  return 0;
}

The program builds and runs as expected, but "nm -C" shows that it contains the following symbols:

000000000040065a W void Dispatcher<1, 2, 3>::call1<int>(bool, bool, int*, int)
000000000040065a W void Dispatcher<1, 2, 3>::call1<int>(bool, bool, int*, int)
00000000004006a4 W void Dispatcher<1, 2, 3>::call2<int>(bool, bool, int*, int)

Without unmangling, they are:

000000000040065a W _ZN10DispatcherILi1ELi2ELi3EE5call1IIiEEEvbbPiDpT_
000000000040065a W _ZN10DispatcherILi1ELi2ELi3EE5call1IJiEEEvbbPiDpT_
00000000004006a4 W _ZN10DispatcherILi1ELi2ELi3EE5call2IiEEvbbPiT_

Why does the function "call1" show up twice but "call2" shows up only once? It looks like it has something to do with the variadic template argument...

I am building using gcc version 4.8.5 with the "-std=c++11 -O0" flags. (I get the issue even with -03 in my real code but the test program gets inlined without -O0.)

Aucun commentaire:

Enregistrer un commentaire