c++ templates metaprogramming endianness

¿Hay alguna manera de hacer una aserción en tiempo de compilación del estilo de C++ para determinar el endianness de la máquina?



templates metaprogramming (3)

Tengo un código de serialización de bajo nivel con plantilla, y necesito saber el endianness del sistema en tiempo de compilación obviamente (porque las plantillas se especializan en función del endianismo del sistema).

En este momento tengo un encabezado con algunas definiciones de plataforma, pero prefiero tener alguna forma de hacer aserciones sobre endianness con alguna prueba de plantilla (como static_assert o boost_if). La razón por la que mi código deberá compilarse y ejecutarse en una amplia gama de máquinas, de muchos proveedores especializados y, probablemente, de dispositivos que no existen en 2008, por lo que no puedo adivinar qué podría necesitar entrar en ese encabezado de años. por el camino. Y dado que la base de código tiene una vida útil esperada de aproximadamente 10 años. Entonces no puedo seguir el código para siempre.

Espero que esto aclare mi situación.

Entonces, ¿alguien sabe de una prueba en tiempo de compilación que puede determinar endianness, sin depender de definiciones específicas del proveedor?


Hmm, esa es una pregunta interesante. Mi apuesta es que esto no es posible. Creo que debes seguir usando macros, e ir con BOOST_STATIC_ASSERT(!BIG_ENDIAN); , o static_assert en c ++ 0x. La razón por la que creo que esto es porque endian''nes es una propiedad si su entorno de ejecución. Sin embargo, static_assert se considera en tiempo de compilación.

Sugiero que busque en el código del nuevo engarce ELF de oro de GNU . Ian Lance Taylor, su autor, usó plantillas para seleccionar el endianness correcto en tiempo de compilación, para asegurar un rendimiento óptimo en tiempo de ejecución. Él ejemplifica explícitamente todos los posibles endians, de modo que todavía tiene una compilación separada (no todas las plantillas en los encabezados) de la definición y declaración de la plantilla. Su código es excelente.


No existe una forma portátil de hacerlo en tiempo de compilación, la mejor opción es utilizar las macros de Endpoint Boost o emular los métodos que utilizan.


Si usa autoconf, puede usar la macro AC_C_BIGENDIAN , que está bastante garantizada para funcionar (configurando WORDS_BIGENDIAN define de forma predeterminada)

alternativamente, puede intentar algo como lo siguiente (tomado de autoconf) para obtener una prueba que probablemente se optimice (GCC, al menos, elimina la otra rama)

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; }