I'm using C++11 on a project of mine and was wondering how best to represent the ELF magic number. I'm not a fan of hex literals, so I was looking for something better than:
const uint32 ELF_MAGIC_NUMBER = 0x7F454c46; // 0x7F, E, L, F
So, I tried to write:
const uint32 ELF_MAGIC_NUMBER = { 0x7F, 'E', 'L', 'F' };
but the compiler complains that there are too many items in the initializer list, which is understandable, although annoying.
Is there any way to write an integer literal in terms of its bytes? I feel like the first option, while it works, is not as readable at the second.
Since you can afford C++11, you could just define a little constexpr
helper, which would enable compile-time evaluation:
#include <cstdint>
constexpr std::uint32_t from_bytes(char b1, char b2, char b3, char b4)
{
return b4 +
(static_cast<std::uint32_t>(b3) << 8) +
(static_cast<std::uint32_t>(b2) << 16) +
(static_cast<std::uint32_t>(b1) << 24);
}
This way, your code won't look much different from the original version:
const std::uint32_t ELF_MAGIC_NUMBER = from_bytes(0x7F, 'E', 'L', 'F');
int main()
{
static_assert(ELF_MAGIC_NUMBER == 0x7F454c46, "!");
}
Here is a live example.
Many compilers have this little known feature: multi-char character literals.
uint32 ELF_MAGIC_NUMBER = '\177ELF';
You'll have to use octal numbers for the non char, I'm afraid.
Ah, almost forgot! The meaning of that is compiler dependent, so I wouldn't do it.
But if you can use C++11 you can use constexpr
and user-defined literals:
constexpr uint32_t operator "" _mc (const char *str, size_t len)
{
return len==4?
(str[0] << 24) | (str[1] << 16) | (str[2] << 8) | str[3] :
throw "_mc literal must be of length 4";
}
constexpr uint32_t ELF_MAGIC_NUMBER = "\177ELF"_mc;
This has the nice feature that you can use string concatenation to use hexadecimal characters:
constexpr uint32_t ELF_MAGIC_NUMBER = "\x7F""ELF"_mc;
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