Lorenzo Pistone
Lorenzo Pistone

Reputation: 5188

template linking error

I have an header, where I put the definition of a function template:

template <typename FT, typename std::enable_if< !std::is_array<FT>::value, int >::type =0 >
int fieldRW(lua_State* l, FT* ptr, bool write){ return scalarFieldRW<FT>(l, ptr, write); }

in a .cpp unit I get a pointer to this template function, and I expect the compiler to instantiate the template:

typedef int (*_fieldRW)(lua_State*, void*, bool);
int dummy=3;
_fieldRW aFunctionPointer=_fieldRW(fieldRW<decltype(dummy)>);

Everything compiles. But I get the following link-time error:

/home/pisto/sorgenti/hopmodv4/src/fpsgame/server.cpp:39: undefined reference to `int fieldRW(lua_State*, int*, bool)'

Notice that the compiler correctly picks the template defined in the header (because it adds the default second argument of the template), but apparently it fails to actually instantiate the template.

EDIT: this looks definitely like a bug. See these tests: http://pastebin.com/5Yjsv47H Also, another clue that this is likely to be a bug in g++ is that if I do this:

int main() {
        int dummy=3;
        int (*inted)(int*)=asd<decltype(dummy)>;
        int (*voided)(void*)=(int (*)(void*))asd<decltype(dummy)>;
        voided(&dummy);
}

g++ warns about the unused variable inted but compiles finely.

Upvotes: 0

Views: 108

Answers (1)

Lorenzo Pistone
Lorenzo Pistone

Reputation: 5188

The answer is probably a subtleness in the specs of function pointer casting:

The standard says in [expr.reinterpret.cast] "A function pointer can be explicitly converted to a function pointer of a different type. The effect of calling a function through a pointer to a function type (8.3.5) that is not the same as the type used in the definition of the function is undefined."

So I think the program has undefined behaviour. Because you never call asd as part of a valid expression it doesn't need to be instantiated.

Clang++ fails in the same way as G++ 4.6, but it works with G++ 4.7

(Thanks to Jonathan Wakely)

Upvotes: 1

Related Questions