C макроса для создания битовой маски - возможно? И обнаружил ли я ошибку GCC?

Мне несколько любопытно создание макроса для генерации битовой маски для регистра устройства, до 64 бит. Таким образом, BIT_MASK (31) производит 0xffffffff .

Однако несколько примеров на C не работают должным образом, так как вместо них я получаю 0x7fffffff . Это как если бы компилятор предполагал, что мне нужен подписанный вывод, а не беззнаковый. Итак, я попробовал 32 и заметил, что значение возвращается обратно к 0. Это связано со стандартами C, в которых говорится, что если значение сдвига больше или равно количеству бит в операнде, которое нужно сдвинуть , то результат не определен. В этом есть смысл.

Но, учитывая следующую программу, bits2.c :

#include <stdio.h>

#define BIT_MASK(foo) ((unsigned int)(1 << foo) - 1)

int main()
{
    unsigned int foo;
    char *s = "32";

    foo = atoi(s);
    printf("%d %.8x\n", foo, BIT_MASK(foo));

    foo = 32;
    printf("%d %.8x\n", foo, BIT_MASK(foo));

    return (0);
}


Если я скомпилирую с помощью gcc -O2 bits2.c -o bits2 и запустил ее на Linux / На машине x86_64 я получаю следующее:

32 00000000
32 ffffffff


Если я возьму тот же код и скомпилирую его на машине Linux / MIPS (big-endian), я получу следующее:

32 00000000
32 00000000


На машине x86_64, если я использую gcc -O0 bits2.c -o bits2 , тогда я получу:

32 00000000
32 00000000


Если я настрою BIT_MASK на ((unsigned int) (1UL << foo) - 1) , то результат будет 32 00000000 для обеих форм, независимо от уровня оптимизации gcc.

Похоже, что на x86_64 gcc что-то оптимизирует неправильно ИЛИ неопределенный характер сдвига влево 32 бита для 32-битного числа определяется аппаратным обеспечением каждой платформы.




Учитывая все вышесказанное, можно ли программно создать макрос C, который создает битовую маску либо из одного бита, либо из диапазона битов?

То есть:

BIT_MASK(6) = 0x40
BIT_FIELD_MASK(8, 12) = 0x1f00

Предположим BIT_MASK и BIT_FIELD_MASK работают с 0-индексом (0-31). BIT_FIELD_MASK предназначен для создания маски из диапазона битов, то есть 8:12 .

14
задан Kumba 8 January 2012 в 01:10
поделиться