G ++ and clang different behavior with recursively creating a bitrate template set (maybe a gcc error?)

The following code produces dramatically different results when compiling with g ++ or with clang ++ . Sorry for the long example, but I could not make it shorter.

A program must assign a specific bit position to a specific type, and then build std::bitsetone containing several type bits.

#include <bitset>
#include <iostream>

using namespace std;
using Bts = bitset<32>;

int getNextId() { static int last{0}; return last++; }

template<class T> struct IdStore{ static const int bitIdx; };
template<class T> const int IdStore<T>::bitIdx{getNextId()};

template<class T> void buildBtsHelper(Bts& mBts) { 
    mBts[IdStore<T>::bitIdx] = true; 
}
template<class T1, class T2, class... A> 
void buildBtsHelper(Bts& mBts) { 
    buildBtsHelper<T1>(mBts); buildBtsHelper<T2, A...>(mBts); 
}
template<class... A> Bts getBuildBts() { 
    Bts result; buildBtsHelper<A...>(result); return result; 
}

template<class... A> struct BtsStore{ static const Bts bts; };
template<class... A> const Bts BtsStore<A...>::bts{getBuildBts<A...>()};
template<> const Bts BtsStore<>::bts{};

template<class... A> const Bts& getBtsStore() { 
    return BtsStore<A...>::bts; 
}

struct Type1 { int k; };
struct Type2 { float f; };
struct Type3 { double z; };
struct Type4 { };

int main()
{
    cout << getBtsStore<Type1, Type2, Type3, Type4>() << endl;
    return 0;
}
  • g ++ 4.8.2 prints -----:00000000000000000000000000000001
  • clang ++ SVN prints: 00000000000000000000000000001111(as expected)

Only compilation flag -std=c++11.

What's happening? Do I represent undefined behavior? Is g ++ right?

+4
3

:

template<class T> const int IdStore<T>::bitIdx{getNextId()};

template<class... A> const Bts BtsStore<A...>::bts{getBuildBts<A...>()};
// getBuildBts uses IdStore<T>::bitIdx as indexes to assign

IdStore<T>::bitIdx BtsStore<A...>::bts, . BtsStore<A...>::bts, g++. :

3.6.2

2 (...) , . . (. ) .

+6

, IdStore::bitIdx -, .

+2

zch .

IdStore Type1, Type2, Type3 Type4 , , , . Type1, Type2, Type3 Type4.

template struct IdStore<Type1>;
template struct IdStore<Type2>;
template struct IdStore<Type3>;
template struct IdStore<Type4>;

. Vittorio, . . IdStore :

template <typename T>
int IdStore() {
    return getNextId();
}

buildBtsHelper :

mBts[IdStore<T>()] = true;
+1

All Articles