Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining endianness with htons

Consider the following code:

#include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[]) {
    uint16_t num = 123;

    if (htons(num) == num) {
        printf("big endian\n");
    } else {
        printf("little endian\n");
    }
}

I'm wondering whether this code works for checking endianness? I've seen many questions checking it with various pointer/char tricks, but I figure this is simpler. It works off the assumption that if you convert a number to network-byte order (big endian), if it is the same as the original number then you're on a big endian system. Otherwise you're on a little endian system.

Is there a false assumption in this check? Perhaps maybe network-byte order isn't always big endian, though it seems it is standardised to be so.

like image 977
Daniel Porteous Avatar asked Feb 05 '23 10:02

Daniel Porteous


1 Answers

This is sufficient to check for endianness at run time.

On big endian systems, htons (as well as ntohs, htonl, and ntohl) are defined as no-ops, while on little endian systems they perform a byte swap.

EDIT:

This can also be done using a union. The check below detects big and little endian, as well as other more exotic byte orderings.

#include <stdio.h>
#include <stdint.h>

union echeck {
    uint32_t i;
    char c[4];
} echeck = { .c = { 0x01, 0x02, 0x03, 0x04 } };

int main()
{
    if (echeck.i == 0x01020304) {
        printf("big endian\n");
    } else if (echeck.i == 0x04030201) {
        printf("little endian\n");
    } else if (echeck.i == 0x02010403) {
        printf("pdp endian\n");
    } else {
        printf("other endian\n");
    }
    return 0;
}
like image 66
dbush Avatar answered Feb 08 '23 14:02

dbush