Мне кажется, проблема в том, что компилятор не может гарантировать, что указатель стека будет правильно выровнен, когда он собирается создать объект _Vector3D
в стеке для передачи конструктору.
В 32-битных системах указатели стека обычно гарантированно выровнены на 4 байта (иногда выровнены на 8 байт), а в 64-битных системах я думаю, что указатель стека обычно гарантированно выровнен на 8 байт, поэтому компилятор не знает, когда он вызовет конструктор, чтобы стек был выровнен правильно. Возможно, вам придется передать указатель или ссылку.
Обратите внимание, что malloc()
и друзья, гарантированное выравнивание, возвращаемое для блока, иногда не может обрабатывать специальные типы, подобные этому. В этом случае платформа будет иметь специальную функцию выделения для распределения этих объектов.
Подробнее о MSVC см. Ниже (http://msdn.microsoft.com/en-us/library/aa290049.aspx):
Выравнивание стека
На обеих 64-битных платформах верх каждого стекового кадра выравнивается по 16 байтов. Хотя при этом используется больше места, чем необходимо, это гарантирует, что компилятор может разместить все данные в стеке таким образом, чтобы все элементы были выровнены.
Компилятор x86 использует другой метод для выравнивания стека. По умолчанию стек выравнивается по 4 байта. Несмотря на то, что это экономит место, вы можете видеть, что есть некоторые типы данных, которые должны быть выровнены по 8 байтам, и что для получения хорошей производительности иногда требуется 16-байтовое выравнивание. В некоторых случаях компилятор может определить, что динамическое 8-байтовое выравнивание стека было бы полезным, особенно когда в стеке есть двойные значения.
Компилятор делает это двумя способами. Во-первых, компилятор может использовать генерацию кода времени компоновки (LTCG), когда это указано пользователем во время компиляции и компоновки, для генерации дерева вызовов для всей программы. При этом он может определить области дерева вызовов, в которых было бы полезно выравнивание стека 8 байтов, и определить сайты вызовов, где динамическое выравнивание стека получает наилучшую отдачу. Второй способ используется, когда функция имеет двойные значения в стеке, но по какой-либо причине еще не выровнена по 8 байтов. Компилятор применяет эвристику (которая улучшается с каждой итерацией компилятора), чтобы определить, должна ли функция быть выровнена динамически в 8 байтов.
Примечание. Недостатком динамического 8-байтового выравнивания стека с точки зрения производительности является то, что отсутствие указателя кадра (/ Oy) эффективно отключается. Регистр EBP должен использоваться для ссылки на стек с динамическим 8-байтовым стеком, и поэтому он не может использоваться в качестве общего регистра в функции.
В приведенной выше статье также есть некоторая информация о специальных функциях кучи, которые обеспечивают гарантии выравнивания выше, чем у стандарта malloc()
, если вам это нужно.