Сбой на любом уровне оптимизации, кроме -o0 в iOS - PullRequest
3 голосов
/ 24 февраля 2012

Следующие два фрагмента кода работают нормально, когда уровень оптимизации равен -o0. Но когда уровень оптимизации отличается от -o0, в первый момент происходит сбой первого кода, но не происходит секунд. не могли бы вы объяснить, почему?

1

unsigned char* _pos = ...;

double result;

*((int*)&result) = *((int*)_pos;

2

unsigned char* _pos = ...;
double result;

int* curPos = (int*)_pos;
int* resultPos = (int*)&result;
*resultPos = *curPos;

EDIT: Кстати, этот код находится во встроенной функции. Когда функция не встроена, сбой не происходит даже при оптимизации.

1 Ответ

4 голосов
/ 25 февраля 2012

Код на самом деле приводит к нескольким проблемам одновременно.Во-первых, как было сказано ранее, код нарушает правила псевдонимов и, следовательно, результат не определен для стандарта.Так что, строго говоря, компилятор может делать кучу вещей при оптимизации (это на самом деле ваш случай, когда вышеупомянутый код встроен).

Второй (и я считаю, что это и есть настоящая проблема здесь) - приведение char *к int * будет увеличивать предполагаемое выравнивание указателя.В соответствии с вашей платформой ABI, char может быть выровнен на 1 байт, а int - не менее 4 (double выровнен на 8 байт, кстати).Система может выдерживать невыровненные нагрузки, но не всегда, например, на arm / darwin она может выдерживать 4-байтовые невыровненные нагрузки, но не 8. Последний случай может произойти, когда компилятор решит объединить две последовательные нагрузки / сохраненные в 1. Так как выУдар по фактическому выравниванию компилятора указателя может сделать вывод, что все выровнено подходящим образом и сгенерировать 8-байтовые нагрузки.

Итак, вкратце - исправьте ваш код :) В этом конкретном случае вам поможет memcpy / memmove.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...