htonl() vs __builtin_bswap32()

让人想犯罪 __ 提交于 2019-12-04 10:09:59

Just look at source code : (example from glib 2.18)

#undef htonl
#undef ntohl

uint32_t
htonl (x)
uint32_t x;
{
    #if BYTE_ORDER == BIG_ENDIAN
       return x;
    #elif BYTE_ORDER == LITTLE_ENDIAN
       return __bswap_32 (x);
    #else
       # error "What kind of system is this?"
    #endif
}
weak_alias (htonl, ntohl)

And : #define __bswap_32(x) ((unsigned int)__builtin_bswap32(x))

Source here : http://fossies.org/dox/glibc-2.18/htonl_8c_source.html

As you can see, htonl only call __builtin_bswap32 on little-endian machines.

I disagree with your statement that htonl() is used to reverse byte order. It is used to convert from host to network byte order. Depending on the byte order of the host, that may, or may not, result in byte order being reversed.

I suggest that you use the function that expresses the correct semantic intent:

  • If you wish to convert from host to network byte order, use htonl().
  • If you wish to reverse byte order, use __builtin_bswap32().

bswap_32 always reverse byte order, on any architecture.

htonl/ntohl reverses byteorder on little endian machines only.

For example, on PowerPC (big endian), ntohl/htonl just returns input value, no more, while bswap32 anyway will reverse byte order.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!