Просто нашел причину коварного сбоя в том, что компилятор не проверяет , не обращая внимания на типы.Это предполагаемое поведение или ошибка компилятора?
Проблема : Когда задействовано определение типа, можно сделать неявное переосмысление приведения, подрывая систему типов.
#include <iostream>
template<class A, class B>
inline bool
isSameObject (A const& a, B const& b)
{
return static_cast<const void*> (&a)
== static_cast<const void*> (&b);
}
class Wau
{
int i = -1;
};
class Miau
{
public:
uint u = 1;
};
int
main (int, char**)
{
Wau wau;
using ID = Miau &;
ID wuff = ID(wau); // <<---disaster
std::cout << "Miau=" << wuff.u
<< " ref to same object: " <<std::boolalpha<< isSameObject (wau, wuff)
<< std::endl;
return 0;
}
Я был шокирован, обнаружив, что gcc-4.9, gcc-6.3 и clang-3.8 принимают этот код без ошибок и выдают следующий вывод:
Miau=4294967295 ref to same object: true
Пожалуйстапримечание: я использую синтаксис конструктора типа ID(wau)
.Я ожидал бы такого поведения на бросках в стиле C, то есть (ID)wau
.Только при использовании синтаксиса фигурных скобок нового стиля ID{wau}
мы получаем ожидаемую ошибку ...
~$ g++ -std=c++11 -o aua woot.cpp
woot.cpp: In function ‘int main(int, char**)’:
woot.cpp:31:21: error: no matching function for call to ‘Miau::Miau(<brace-enclosed initializer list>)’
ID wuff = ID{wau};
^
woot.cpp:10:7: note: candidate: constexpr Miau::Miau()
class Miau
^~~~
woot.cpp:10:7: note: candidate expects 0 arguments, 1 provided
woot.cpp:10:7: note: candidate: constexpr Miau::Miau(const Miau&)
woot.cpp:10:7: note: no known conversion for argument 1 from ‘Wau’ to ‘const Miau&’
woot.cpp:10:7: note: candidate: constexpr Miau::Miau(Miau&&)
woot.cpp:10:7: note: no known conversion for argument 1 from ‘Wau’ to ‘Miau&&’
К сожалению, синтаксис фигурных скобок часто не используется в шаблонном тяжелом коде из-заstd::initializer_list
фиаско.Так что для меня это серьезная проблема, так как защита системой типов здесь фактически ломается.
- Может кто-нибудь объяснить причину такого поведения?
- Это какая-тообратная совместимость (опять вздох)?