MSVC 2013 - link error, ODR violation
От: Кодт Россия  
Дата: 13.03.15 13:46
Оценка: 21 (4)
Помните, как VC6 сходил с ума на специализациях шаблонов функций с одинаковым типом
template<class T> void fun() {}
int main() { f<int>(); f<char>(); }

потому что компилятор давал им одинаковое манглированное имя? А линкер потом наобум брал любую специализацию и подсовывал во все места, нарушая ODR.

Встречайте:
#include <cstdio>

template< template<class>class F > struct say
{
    static void hello() { puts(__FUNCSIG__); }
};

template<class> struct alfa {};
template<class> struct beta {};

template<class> using blue = void;
template<class T> using star = T***;

int main()
{
    say<alfa>::hello(); // ?hello@?$say@Ualfa@@@@SAXXZ (public: static void __cdecl say<struct alfa>::hello(void))
    say<beta>::hello(); // ?hello@?$say@Ubeta@@@@SAXXZ (public: static void __cdecl say<struct beta>::hello(void))
    say<blue>::hello(); // ?hello@?$say@$@@SAXXZ       ( ?? ?? ::SAXXZ::say<>::hello)
    say<star>::hello(); // ?hello@?$say@$@@SAXXZ       ( ?? ?? ::SAXXZ::say<>::hello)
}

На этот раз линкер заругался, что в одной секции кода две точки с одинаковым именем. (Кстати, уже весело, невалидный .obj)
Но если похимичить с несколькими единицами трансляции, то — ТАДАМ!!!


Ну и приятная новость для пользователей MSVC 2015: там этот баг уже исправлен.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.