Разыменование указателя типа-наказание нарушает правила строгого наложения имен - PullRequest
0 голосов
/ 02 июня 2018

В процессе компиляции отображается следующая ошибка:

ccm.c:152:5: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
      HWREG(AES_AES_IV_0) = ((uint32_t *)&ui8A0)[0];

ccm.c:325:5: error: dereferencing type-punned pointer will break strict- aliasing rules [-Werror=strict-aliasing]
      ((uint32_t  *)&ui8MIC)[0] = HWREG(AES_AES_TAG_OUT_0);

Строка 152-155:

HWREG(AES_AES_IV_0) = ((uint32_t  *)&ui8A0)[0];
HWREG(AES_AES_IV_1) = ((uint32_t  *)&ui8A0)[1];
HWREG(AES_AES_IV_2) = ((uint32_t  *)&ui8A0)[2];
HWREG(AES_AES_IV_3) = ((uint32_t  *)&ui8A0)[3];

ui8A0 имеет размер 16 uint8_t массив:

uint8_t  ui8A0[16];

Строка 325-328:

((uint32_t  *)&ui8MIC)[0] = HWREG(AES_AES_TAG_OUT_0);
((uint32_t  *)&ui8MIC)[1] = HWREG(AES_AES_TAG_OUT_1);
((uint32_t  *)&ui8MIC)[2] = HWREG(AES_AES_TAG_OUT_2);
((uint32_t  *)&ui8MIC)[3] = HWREG(AES_AES_TAG_OUT_3);

ui8MIC имеет размер 16 uint8_t массив:

uint8_t volatile ui8MIC[16];

Внешний вид макроса HWREGвот так:

#define HWREG(x)                                                              \
        (*((volatile uint32_t *)(x)))

Вот как я это понимаю: ui8A0 - это массив, &ui8A0 - это адрес первого элемента, (uint32_t *)&ui8A0 - это адрес для массива, где элементы uint32_t противоположны uint8_t((uint32_t *)&ui8A0)[0] - это значение первого элемента массива, элементами которого являются uint32_t.

Таким образом, в основном этот код должен передать 4 элемента макроса ui8A0 в HWREG.

Похоже на эту проблему: https://stackoverflow.com/a/20956250/1625856 Но я бы предпочел не использовать решение на основе объединения.

Есть ли другой, более простой способ справиться с этим?

Моя единственная идея - заменить:

HWREG(AES_AES_IV_1) = ((uint32_t  *)&ui8A0)[1];

на:

HWREG(AES_AES_IV_1) = (uintptr_t)&ui8A0[4];
...