Home  >  Article  >  Backend Development  >  How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C ?

How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C ?

Susan Sarandon
Susan SarandonOriginal
2024-10-30 04:37:28813browse

How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C  ?

Portability Concerns for Network Byte Order Conversions of 64-Bit Integers in C

In C , the necessity arises to convert 64-bit integers to "network byte order" for specific applications, such as implementing the memcache protocol. Despite the existence of the htonl() function for converting 32-bit integers, a similar function for 64-bit integers (htonll()) remains elusive.

Standard Function Considerations

Unfortunately, there is currently no portable standard function in C that can perform 64-bit network byte order conversions. This absence creates the need for custom implementations.

Custom Implementation

To implement htonll(), we must first determine the system's endianness. One reliable method is to evaluate the value of an integer variable with known byte ordering (e.g., 42) at runtime:

<code class="cpp">static const int num = 42;
bool isBigEndian = (*reinterpret_cast<const char *>(&num) == num);</code>

Next, we can perform the conversion according to the endianness:

<code class="cpp">uint64_t htonll(uint64_t value)
{
    if (isBigEndian)
    {
        const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
        const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));

        return (static_cast<uint64_t>(low_part) << 32) | high_part;
    }
    else
    {
        return value;
    }
}

Macros for Portability

Alternatively, macros can provide a concise way to define htonll() and its counterpart, ntohll():

<code class="cpp">#define htonll(x) ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))</code>

These macros rely on the system's intrinsic byte ordering behavior to determine the necessary byte-swapping.

Compiler-Specific Macros

Some compilers and operating systems provide specific macros for determining endianness. For example, on systems that support it, we can use:

<code class="cpp">#if __BIG_ENDIAN__
# define htonll(x) (x)
# define ntohll(x) (x)
#else
# define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
#endif</code>

By employing these techniques, custom implementations of htonll() and ntohll() can be made portable across various systems and compilers.

The above is the detailed content of How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn