Я пытаюсь сделать программу скомпилированной с GCC и использую QT и SSE intrinsics. Кажется, что, когда одна из моих функций вызвана QT, выравнивание стека не сохраняется. Вот короткий пример для иллюстрирования то, что я имею в виду:
#include <cstdio>
#include <emmintrin.h>
#include <QtGui/QApplication.h>
#include <QtGui/QWidget.h>
class Widget: public QWidget {
public:
void paintEvent(QPaintEvent *) {
__m128 a;
printf("a: 0x%08x\n", ((void *) &a));
}
};
int main(int argc, char** argv)
{
QApplication application(argc, argv);
Widget w;
w.paintEvent(NULL); // Called from here, my function behaves correctly
w.show();
w.update();
// Qt will call Widget::paintEvent and my __m128 will not be
// aligned on 16 bytes as it should
application.processEvents();
return 0;
}
Вот вывод:
a: 0x0023ff40 // OK, that's aligned on 16 bytes
a: 0x0023d14c // Not aligned!
Конфигурация:
Я пытался скомпилировать пример программы с теми же опциями как те, которых я видел в спокойном make-файле:
-O2 -Wall -frtti -fexceptions -mthreads
, опции ссылки:
-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads
Теперь я не знаю в который направления искать. Любые подсказки ценились бы.Спасибо!
Fabien
Вы можете использовать параметр -mstackrealign
, чтобы сделать это без добавления атрибутов в исходный код:
-mstackrealign Повторно выровняйте стек при входе. На Intel x86 опция -mstackrealign генерирует альтернативный пролог и эпилог, которые при необходимости перестраивают стек выполнения. Это поддерживает смешивание устаревших кодов, которые поддерживают 4-байтовый стек, выровненный с современными кодами, которые поддерживают 16-байтовый стек для совместимости с SSE. См. Также атрибут force_align_arg_pointer, применимый к отдельным функциям.
(из документов GCC )
__attribute__((force_align_arg_pointer)) void paintEvent(QPaintEvent *);
получилось! У кого-нибудь есть лучшее решение?