Мне нужно перенести исходный код с платформы ARM, на которой работает Linux. К сожалению, у меня возникли проблемы с выравниванием памяти. Источник использует приведение указателей и интенсивный доступ.
Код, подобный приведенному ниже, распространяется по кодовой базе как вирус. Я могу точно определить проблемные места благодаря опции командной строки gcc -Wcast-align
, но есть более тысячи экземпляров.
u = (IEC_BOOL);
(((*(IEC_LINT*)pSP).H < b.H)
|| (((*(IEC_LINT*)pSP).H == b.H) && ((*(IEC_LINT*)pSP).L < b.L) )) ? 1 : 0);
*(IEC_DWORD OS_SPTR *)pSP =
(IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP >> u);
*(IEC_DWORD OS_SPTR *)pSP =
(IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP << -u);
u = (IEC_BYTE)((*(IEC_DINT*)pSP != b) ? 1 : 0);
*(IEC_DWORD*)pSP = (IEC_DWORD)(*(IEC_DWORD*)pSP & w);
(*(IEC_ULINT*)pSP).H += u.H;
(((*(IEC_ULINT OS_SPTR *)pSP).H == b.H)
&& ((*(IEC_ULINT OS_SPTR *)pSP).L > b.L))) ? 1 : 0);
u = (IEC_BYTE)((*(IEC_REAL*)pSP >= b) ? 1 : 0);
Использование echo 2 > /proc/cpu/alignment
on позволяет ядру Linux устранять проблемы, но производительность приложения снижается до уровня, который больше не является приемлемым.
Я искал в сети что-то похожее на ключевое слово __unaligned
или __packed
для компилятора GCC (v4.4.1), но пока еще пусто.
Я думал, что многие строки кодового кода могут быть исправлены с помощью более или менее сложного регулярного выражения / замены, но теперь, после некоторого времени, я вижу, что этот подход также потребует огромного количества утомительной работы.
Ребята, есть ли у вас какие-либо предложения, как выполнить эту работу? Я думаю, что плагин компилятора gcc 4.5 был бы излишним, но есть ли что-то лучше, чем регулярные выражения? какие еще предложения вы можете придумать? Не обязательно все проблемные случаи должны быть исправлены, так как я все еще могу полагаться на Ядро для нескольких более редких случаев.