Пуннинг типов — как компилятор решает, какой тип использовать?

я читал этот вопрос здесь о решении порядка байтов и первый ответ несколько озадачил меня.

Код, используемый для определения больших порядков байтов, выглядит следующим образом:

int is_big_endian(void)
{
union {
uint32_t i;
char c[4];
} bint = {0x01020304};

return bint.c[0] == 1;
}

Мой вопрос как компилятор решает, какой тип использовать для этого массива шестнадцатеричных цифр? Потому что технически он одинаково хорошо подходит как для uint32_t или это char[4],

Почему бы просто не сохранить его в char[4] и пропустить union?

Есть ли какое-то преимущество union вот чего я не вижу? Я знаю, что это называется наказанием, но я не вижу здесь его преимущества.

3

Решение

Мой вопрос: как компилятор решает, какой тип использовать для этого массива шестнадцатеричных цифр?

Как и в случае массивов и агрегатных классов, первый инициализатор инициализирует первый член; в этом случае i, (Конечно, в отличие от этих вещей, не имеет смысла иметь более одного инициализатора).

Почему бы просто не сохранить его в char [4] и пропустить объединение? Есть ли здесь какое-то преимущество союза, которого я не вижу?

Цель этого состоит в том, чтобы инициализировать 4-байтовое целое число, а затем использовать char массив для проверки отдельных байтов для определения порядка памяти. Если самый значимый байт (0x01) сохраняется в первом байте, затем система является «старшим порядком байтов»; в противном случае это «little-endian» (или, возможно, что-то незнакомое).

6

Другие решения

Исходный стандарт C позволял назначать значение только первому элементу объединения. Это означает: 0x1020304 присваивается «i», а не «c».

Последний стандарт C позволяет присваивать любому члену подобное:

union { ... } bint = { .c = {1,2,3,4} };
union { ... } bint2 = { .i = 0x1020304 };

Однако, как уже было сказано, если имя не указано, то значение присваивается «i».

2

Потому что вы хотите хранить 0x01020304 как 32-разрядное целое число без знака uint32_t i а потом читать первый байт char c[0],

0
По вопросам рекламы [email protected]