У меня есть код C, который анализирует упакованные/неадаптированные двоичные данные, поступающие из сети.
Этот код был/работает отлично под Intel/x86, но когда я скомпилировал его под ARM, он часто падал.
Преступник, как вы могли догадаться, был негласным указателем - в частности, код синтаксического анализа привел бы к таким сомнительным вещам:
uint8_t buf[2048];
[... code to read some data into buf...]
int32_t nextWord = *((int32_t *) &buf[5]); // misaligned access -- can crash under ARM!
... что, очевидно, не собирается летать на ARM-land, поэтому я изменил его, чтобы выглядеть более как это:
uint8_t buf[2048];
[... code to read some data into buf...]
int32_t * pNextWord = (int32_t *) &buf[5];
int32 nextWord;
memcpy(&nextWord, pNextWord, sizeof(nextWord)); // slower but ARM-safe
Мой вопрос (с точки зрения языка-юриста) заключается в следующем: мой подход "ARM-fixed" хорошо определен в соответствии с правилами языка C?
Мое беспокойство заключается в том, что, возможно, даже просто иметь неправильный-int32_t-указатель может быть достаточно, чтобы вызывать неопределенное поведение, даже если я никогда не разглажу его напрямую. (Если мое беспокойство действительно, я думаю, что я мог бы исправить эту проблему, изменив тип pNextWord
от (const int32_t *)
до (const char *)
, но я бы предпочел не делать этого, если это действительно необходимо сделать, поскольку это означающее выполнение некоторой арифметики указателя-шага вручную)