Когда использовать __bswap_constant_XX вместо __bswap_XX? - PullRequest
1 голос
/ 19 апреля 2019

Может кто-нибудь сказать мне, в чем разница между __bswap_constant_XX и __bswap_XX также, когда предпочитать один другому?

Я использую GCC 4.8

1 Ответ

1 голос
/ 19 апреля 2019

Прежде всего, вы не должны обычно использовать символы с двойным подчеркиванием, поскольку они зарезервированы .

Символы, о которых вы говорите, не определяются компилятором, а являются частью вашей библиотеки C. bswap_XX макросы могут использовать встроенную или даже встроенную сборку компилятора, чтобы компилятор генерировал специфичные для процессора инструкции, делая результат неизвестным во время компиляции.

Напротив, __bswap_constant_XX должны оценивать значение с использованием простых выражений C, делая значение константой времени компиляции, если входные данные являются константой времени компиляции.

Такие макросы могут быть определены как:

#define __bswap_constant_16(x)                                  \
  ((__uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))

#define __bswap_constant_32(x)                                  \
  ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) |   \
   (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))

Идея состоит в том, что вы должны использовать __bswap_constant_XX, когда вам нужно значение времени компиляции, например, при определении значения перечисления:

enum myenum {
    MYVALUE = __bswap_constant_16(0x1234)
};

bswap_XX предполагается использовать во всех других случаях.

Обратите внимание, что современный компилятор способен распознавать простые шаблоны замены байтов и генерировать соответствующие инструкции, поэтому на практике это не будет иметь большого значения большую часть времени.

Например, для обеих функций:

uint16_t bswap16(uint16_t x)
{
    return __bswap_constant_16(x);
}

uint32_t bswap32(uint32_t x)
{
    return __bswap_constant_32(x);
}

GCC 4.8.1 создает:

bswap16:
        mov     eax, edi
        rol     ax, 8
        ret
bswap32:
        mov     eax, edi
        bswap   eax
        ret
...