Новый возвращает ноль; вызывающий объект получает новый член … Ошибка оптимизации?

Я надеялся, что кто-то здесь сможет понять, что, по моему мнению, может быть ошибкой MSVC 2010.

У меня есть этот код (как часть гораздо большего проекта):

namespace MyNamespace{

class Foo{
//snip
QPointer<MyNamespace::Baz> :: x;
};

class Baz{
//snip
};

//snip
Foo::Bar(){
x = new MyNamespace::Baz();
ThisFunctionWillSegfaultIfXIsNull(x);
//snip
}

Опять же, имейте в виду, это часть гораздо более крупного проекта, включающего cmake, qt и целый ряд других интересных вещей.

Я проследил это с помощью отладчика. Когда я компилирую этот проект в режиме отладки, все идет как положено. Однако, когда я скомпилирую это как проект Release, x получит значение 0x0000000000000000.

Кроме того, при отслеживании этого в отладчике MSVS (все еще в режиме выпуска) происходит несколько интересных вещей:

  1. Фактически вызывается конструктор для Baz, и «this» имеет допустимое место в памяти внутри конструктора Baz.

  2. После возвращения из конструктора (обратно в Foo::Bar()) значение this (предположительно «Foo») теперь такое же, как значение «this» внутри конструктора Baz (предположительно «Baz»).

  3. Похоже, что ни одна из данных Foo не была потеряна, хотя она, очевидно, изменила адреса памяти.

  4. «This» (как Foo) каким-то волшебным образом увеличивает новый элемент данных типа MyNamespace :: Baz, который содержит все правильные данные, которые были назначены во время конструктора.

Таким образом, очевидно, что оптимизация компилятора делает что-то чрезвычайно мистическое. Опять же, кажется, что это происходит только в режиме Release, что заставляет меня думать, что A) оптимизатор вносит изменения и B) мешает мне получить дополнительную информацию о том, что на самом деле происходит.

Кто-нибудь видел это раньше? Что здесь происходит? Как я могу заставить свою следующую функцию остановить segfaulting, потому что X является нулем?

-1

Решение

Проблема в другом. Помимо отладчика, который подшучивает над вами (как это часто бывает в режиме релиза), new никогда не может вернуться NULL. Если распределение завершится неудачно, оно выдаст исключение, но никогда не вернется NULL,

Вы можете проверить это с помощью некоторых отладочных операторов:

if (x)
std::cout << "x is not NULL";
1

Другие решения

Других решений пока нет …