views:

1001

answers:

3

I have some low level serialization code that is templated, and I need to know the system's endianness at compiletime obviously (because the templates specializes based on the system's endianness).

Right now I have a header with some platform defines, but I'd rather have someway to make assertions about endianness with some templated test (like a static_assert or boost_if). Reason being my code will need to be compiled and ran on a wide range of machines, of many specialized vendor, and probably devices that don't exist in 2008, so I can't really guess what might need to go into that header years down the road. And since the code-base has an expected lifetime of about 10 years. So I can't follow the code for-ever.

Hopefully this makes my situation clear.

So does anyone know of a compile-time test that can determine endianness, without relying on vendor specific defines?

+2  A: 

Hmm, that's an interesting Question. My bet is that this is not possible. I think you have to continue using macros, and go with BOOST_STATIC_ASSERT(!BIG_ENDIAN);, or static_assert in c++0x. The reason i think this is because the endian'nes is a property if your execution environment. However, static_assert is considered at compile time.

I suggest you look into the code of the new GNU gold ELF linker. Ian Lance Taylor, its author, used templates to select the right endianness at compile time, to ensure optimal performance at run time. He explicitely instantiates all possible endians, so that he still has separate compilation (not all templates in headers) of the template definition and declaration. His code is excellent.

Johannes Schaub - litb
Yes I've not been able to figure it out myself, and as you say it might not even be possible. But I've seen the impossible done before for other situations... so maybe, just maybe someone might come up with a great idea here :)
Robert Gould
+8  A: 

There is no portable way to do this at compile time, your best bet is probably to use the Boost endian macros or emulate the methods they use.

Robert Gamble
Thanks for the link to the header. It's a good reference. And similar to what I have.
Robert Gould
+5  A: 

If you're using autoconf, you can use the AC_C_BIGENDIAN macro, which is fairly guaranteed to work (setting the WORDS_BIGENDIAN define by default)

alternately, you could try something like the following (taken from autoconf) to get a test that will probably be optimized away (GCC, at least, removes the other branch)

int is_big_endian()
{
    union {
        long int l;
        char c[sizeof (long int)];
    } u;

    u.l = 1;

    if (u.c[sizeof(long int)-1] == 1)
    {
        return 1;
    }
    else
        return 0;
}
Hasturkun
Thanks, that is a nice trick. And I think I can apply it with a little reengineering. not sure yet, but its a good lead.
Robert Gould