LINUX.ORG.RU

__builtin_bswap16

 


0

1

Использую конструкцию вида:

#if defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
#endif
#if GCC_VERSION < 480
#define __builtin_bswap16(x) (x<<8 | x>>8)
#endif

Но что-то мне в ней не нравится. Хэлп. Вид у неё сомнительный?

PS: Последняя редакция (решение):

#if defined(__GNUC__)
 #if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 8))
  static inline uint16_t __builtin_bswap16(uint16_t x)
  {
    return (x<<8)|(x>>8);
  }
 #endif /* GCC < 4.8.0 */
#endif /* __GNUC__ */

Дополнительная информация.

Deleted

Последнее исправление: Deleted (всего исправлений: 7)

может просто

#define bswap16(x) ((unsigned short)(x)<<8 | (unsigned short)(x)>>8)

А компилятор сам вставит bswap куда надо

mittorn ★★★★★
()
Ответ на: комментарий от SZT

Сдвигать отрицательное число - UB.

Знаю, знаю. Но не предвидится. Так то криво, согласен. Но не предвидится. Хотя, чорт его знает.

Deleted
()
Ответ на: комментарий от Deleted
#if defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
#else
#define GCC_VERSION 0
#endif
#if GCC_VERSION < 480
#define __builtin_bswap16(x) (((unsigned short)(x))<<8 | ((unsigned short)(x))>>8)
#endif
#undef GCC_VERSION
mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 2)
Ответ на: комментарий от mittorn
#define bswap16(x) ((unsigned short)(x)<<8 | (unsigned short)(x)>>8)

Не, плохая идея. У тебя это может сломаться, если кто-то сделает

bswap16(x++)

SZT ★★★★★
()
Ответ на: комментарий от Deleted

__builtin_bswap16 не макрос, потому не знаю, есть ли другие способы определить
Ну можно в конце концов __GNUC__ и __GNUC_MINOR__ напрямую проверять. строчка получится длиннее

mittorn ★★★★★
()
Ответ на: комментарий от mittorn

ну в моём варианте если не gcc оно будет 0

Вот именно, вот именно. В троём компиляторе __builtin_bswap16 определён?

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

__builtin_bswap16 определен в GCC и мимикрирующих под него компиляторах (clang и Intel С Сompiler под линуксом). В древних версиях GCC https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 его например нет под некоторые платформы

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

В древних версиях GCC его например нет под некоторые платформы

Из-за этого и сыр-бор.

Deleted
()
Ответ на: комментарий от mittorn

И меня беспокоит наличие GCC_VERSION в случаях, когда он должен быть undef. Вот это мне не нравится.

Deleted
()
Ответ на: комментарий от Deleted

Ну так #if defined(__GNUC__) проверяет и выставляет там 0.

#if defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
#else
#define GCC_VERSION 0 <----

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

Ну так #if defined(__GNUC__) проверяет и выставляет там 0.

Промежуточный итог. Новая точка отсчёта, так сказать:

#if defined(__GNUC__)
 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
 #if GCC_VERSION < 480
  #define bswap16(x) (((unsigned short)(x))<<8 | ((unsigned short)(x))>>8)
  #define __builtin_bswap16(x) bswap16((unsigned short)(x))
 #endif
 #undef GCC_VERSION
#endif

Прокатит?

Deleted
()
Ответ на: комментарий от SZT

По поводу проблемы с макросом bswap16 я написал в __builtin_bswap16 (комментарий)

Так из-за этого два определения и сделал, вместо одного. Не прокатит?

Deleted
()
Ответ на: комментарий от Deleted

Нет, не прокатит

https://godbolt.org/z/1WiMkz

<source>: In function 'main':
<source>:1:51: warning: operation on 'a' may be undefined [-Wsequence-point]
   #define bswap16(x) (((unsigned short)(x))<<8 | ((unsigned short)(x))>>8)
                                                  ~^~~~~~~~~~~~~~~~~~~~
<source>:2:33: note: in expansion of macro 'bswap16'
   #define m__builtin_bswap16(x) bswap16((unsigned short)(x))
                                 ^~~~~~~
<source>:7:22: note: in expansion of macro 'm__builtin_bswap16'
   unsigned short b = m__builtin_bswap16(a++);
                      ^~~~~~~~~~~~~~~~~~
Compiler returned: 0
SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 2)
Ответ на: комментарий от SZT

Нет, не прокатит

Печалька. Лишнее получается. Ну, значит static inline. А с ним, если signed, только варнинг будет?

Deleted
()
Ответ на: комментарий от Deleted

Нет, не должно там быть никаких варнингов. Хотя может и есть какие-то компиляторы или опции компилятора, при которых компилятор может на это кидать варнинг, я хз. Можешь кастовать макросом, если тебе это прям так важно

SZT ★★★★★
()
Ответ на: комментарий от SZT

Нет, не должно там быть никаких варнингов.

Хорошо. Ну, последняя редакция. Я надеюсь:

#if defined(__GNUC__)
 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10)
 #if GCC_VERSION < 480
  static inline unsigned short __builtin_bswap16(unsigned short x)
  {
    return (x<<8)|(x>>8);
  }
 #endif
 #undef GCC_VERSION
#endif

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

а зачем вообще определять макрос GCC_VERSION а потом его undef делать? Ну как минимум он может быть уже определен. Можно же написать

#if defined(__GNUC__)
  #if (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 8))
  static inline unsigned short __builtin_bswap16(unsigned short x)
  {
    return (x<<8)|(x>>8);
  }
 #endif /* GCC < 4.8.0 */
#endif /* __GNUC__ */

И наверное стоит использовать uint16_t вместо unsigned short

abondarev ★★★
()
Ответ на: комментарий от abondarev

а зачем вообще определять макрос GCC_VERSION

Это притянулось из исходного варианта. И именно это меня смущало.

И наверное стоит использовать uint16_t вместо unsigned short

По-моему, разницы нет.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

И наверное стоит использовать uint16_t вместо unsigned short
По-моему, разницы нет.

для x86 нет. если не будет кросс-компиляции (где могут быть другие размеры типов данных), то это не нужно.

abondarev ★★★
()
Ответ на: комментарий от vodz

Вот это смотрели?

Смотрели. Но за ссылку всё-равно сенькс, сам забыл втемяшить. Интересует всё-таки только gcc.

Deleted
()
Ответ на: комментарий от abondarev

если не будет кросс-компиляции

Твою ж мать. Согласен.

Deleted
()
Ответ на: комментарий от vodz

Тогда непонятно, в чём проблема с #if GCC_VERSION ?

Лишнее определение.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.