Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In my own TCP/IP stack I have defined things like IPv4 addresses and port numbers as unions instead of integers, and given them functions to convert to host order and back. e.g.

    typedef union {
        uint32_t net_order;
        uint8_t byte[4];
    } ipv4_address;
    _Static_assert( sizeof(ipv4_address) == 4, "ipv4_address is not 4 bytes long");

    static inline __attribute__((overloadable)) uint32_t as_host( ipv4_address a) {
        return other_order_32(a.net_order);
    }
    // more functions follow, like 
    //    bool equal(a,b)
    //    int compare(a,b)
    //    ipv4_address ipv4_address_from_host( uint32_t)
The nice part of this is that it would take an act of willful ignorance on my part to accidentally miss or over include a conversion from network order to host order.

The compiler is still happy to slam these around in registers like integers so I haven't changed the runtime performance. The downside is that C won't let you compare structs or unions with ==, so I have to have that equal() function which dirties the source code a bit.

That __attribute__((overloadable)) makes as_host() an overloadable function so I don't have to have a giant family of incredibly_long_function_names to convert all my different types to host byte order or to compare them with themselves.

That _Static_assert isn't terribly useful in this case, but there is one on all of the structures where I expect to have explicitly specified a layout. That way when the compiler tries to pull a fast one on me because some language lawyer spent too long reading the spec, I'll find out at build time.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: