After some search for a way to check endianess at compile-time I've come up with the following solution:
static const int a{1};
constexpr bool is_big_endian()
{
return *((char*)&(a)) == 1;
}
GCC accepts this code only in some contexts where constexpr is required:
int b[is_big_endian() ? 12 : 25]; //works
std::array<int, testendian() ? 12 : 25> c; //fails
For the second case, GCC says error: accessing value of ‘a’ through a ‘char’ glvalue in a constant expression
. I couldn't find anything in the standard that forbids such thing. Maybe someone could clarify in which case GCC is correct?
A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.
Using constexpr to Improve Security, Performance and Encapsulation in C++ constexpr is a new C++11 keyword that rids you of the need to create macros and hardcoded literals. It also guarantees, under certain conditions, that objects undergo static initialization.
The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.
This is what I get from Clang 3.1 ToT:
error: constexpr function never produces a constant expression
§5.19 [expr.const]
p1 Certain contexts require expressions that satisfy additional requirements as detailed in this sub-clause; other contexts have different semantics depending on whether or not an expression satisfies these requirements. Expressions that satisfy these requirements are called constant expressions.
p2 A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression:
- [...]
- a
reinterpret_cast
(5.2.10);
So, (char*)&(a)
evaluates to a reinterpret_cast
, as such the function is never a valid constexpr
function.
You should look into Boost.Detail.Endian
It is a mapping of several architectures to their endianness (through the macros BOOST_BIG_ENDIAN, BOOST_LITTLE_ENDIAN, and BOOST_PDP_ENDIAN). As far as I know, there is no actual way to determine the endianness at compile time, other than a list like this.
For an example implementation that uses Boost.Detail.Endian, you can see the library I'm hoping to get reviewed for submission to Boost: https://bitbucket.org/davidstone/endian/ (the relevant file is byte_order.hpp
, but unsigned.hpp
is necessary as well if you want to just use my implementation).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With