Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, okman, Вы писали:
O>>Или такое присваивание всегда безопасно, даже если сами указатели содержат null или "мусор"?
AG>Я бы не стал присваивать неинициализированный мусор, потому что инструменты статического анализа кода имеют право дважды ругнуться.
AG>Во-первых, мы используем значение неинициализированной переменной.
AG>Во-вторых, мы же потом не разыменовываем целевой указатель, так? Вот и неиспользованное присвоенное значение.
AG>Что до легальности с точки зрения С/С++.
AG>Есть такая штука, как signaling NaN.
AG>Она может привести к тому, что следующее присвоение упадёт:
AG>AG>float f1;
AG>float f2;
AG>f2 = f1;
AG>
AG>Если под это есть "законодательная база" в С/С++, то, возможно, она применима и к указателям.
Я всегда считал, что присваивание одного указателя другому всегда безопасно, даже если
сами указатели указывают "в никуда". Но вот наткнулся на примерно такой код (сильно упрощен):
#include <cstdio>
struct Base
{
virtual ~Base() {}
};
struct X1 : public virtual Base {};
struct X2 : public virtual Base {};
struct Child : public X1, public X2 {};
int main()
{
X1 * p1 = new X1();
delete p1;
Base * p2;
p2 = p1;
printf("p2 = %p\r\n", (void *)p2);
return 0;
}
При запуске на VS2015 или VS2008 в режиме Debug программа падает на строке 'p2 = p1':
"Exception thrown at [...] in MyProgram.exe: 0xC0000005: Access violation reading location [...]".
Аналогично ведут себя онлайн-компиляторы:
codepad (C++) — Segmentation fault
http://codepad.org/ZdbdFm98
ideone (C++14) — Runtime error
https://ideone.com/HRCX3A
rextester (C++ gcc) — Invalid memory reference (SIGSEGV)
http://rextester.com/XKG97608
rextester (C++ clang) — Invalid memory reference (SIGSEGV)
http://rextester.com/GAKSE23949
Ключевой момент — виртуальное наследование X1 и X2 от Base.
Хотелось бы понять, насколько такое поведение (т.е. разыменование указателя, возможно висячего,
при выполнении приведений типов по иерархии наследования) легально с точки зрения стандарта C++.
Или же это сугубо implementation-defined?..