Will it then calculate the endianness at compile time? instead of runtime ? |
Neither, because that doesn't seem to compile. bint isn't constexpr, so try not making it an anonymous union.
But even when I change it to
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#include <iostream>
inline constexpr bool is_big_endian()
{
union Foo {
uint32_t i;
char c[4];
};
constexpr Foo bint = {0x01020304};
constexpr bool check = (bint.c[0] == 1);
return check;
}
int main() {
is_big_endian();
return 0;
}
| |
It still doesn't compile.
1 2 3 4
|
prog.cpp: In function ‘constexpr bool is_big_endian()’:
prog.cpp:11:43: error: accessing ‘is_big_endian()::Foo::c’ member instead of initialized ‘is_big_endian()::Foo::i’ member in constant expression
constexpr bool check = (bint.c[0] == 1);
^
| |
I'm not a standard expert, but in modern C++ I believe "type punning" is undefined behavior (i.e., setting i to be a number, and then getting the first byte of that number through the union), although may still "work" in practice.
https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior/11996970#11996970
There's a bunch of different things you can try, but I don't think any of them are 100% portable.
https://stackoverflow.com/questions/4239993/determining-endianness-at-compile-time
https://gcc.gnu.org/ml/gcc-help/2007-07/msg00342.html
Also, inline these days just means "allow more than one definition of this function", it won't affect it being compile-time or not.
Your is_big_endian function itself is not constexpr. Is this intentional?
_________________________________________
The biggest picture:
What's so bad about it being run-time? It would only need to be calculated once... and then you can put the bool inside a static object to be referenced for the remainder of the program. You wouldn't not notice any difference even if your is_big_endian function did compile.
The only way to actually get rid of complete segments of code at compile time would be with macros "#if ... " which would be different per compiler.
This will compile but it's run-time.
1 2 3 4 5 6 7 8 9 10 11 12 13
|
inline bool is_big_endian()
{
union Foo {
uint32_t i;
char c[4];
};
constexpr Foo bint = {0x01020304};
bool check = (bint.c[0] == 1);
return check;
}
| |