This was unfortunately not practical to post as a comment.
Fixes apart from making ungood literal a compile time error:
- Shift of signed values fixed.
- Use of
throw
without arguments.
- Assumption of 8-bit byte made explicit.
#include <iostream>
#include <stdint.h>
#include <limits.h> // CHAR_BIT
using namespace std;
using Byte = unsigned char;
const int bits_per_byte = CHAR_BIT;
static_assert( bits_per_byte == 8, "!" );
constexpr auto operator "" _int( char const* s, std::size_t len )
-> uint16_t
{ return len == 2 ? Byte( s[0] ) | (Byte( s[1] ) << 8u) : throw "Bah!"; }
#define CHAR_PAIR( s ) static_cast<uint16_t>( sizeof( char[s ## _int] ) )
auto main()
-> int
{
CHAR_PAIR( "AB" ); // OK
CHAR_PAIR( "ABC" ); //! Doesn't compile as ISO C++.
}
With Visual C++ that's all that's needed.
g++ is less standard-conforming in this respect, so for that compiler add option -Werror=vla
.
With g++ you can alternatively use the following macro:
#define CHAR_PAIR( s ) []() constexpr { constexpr auto r = s##_int; return r; }()
This gives a more informative error message, but isn't supported by Visual C++ 2017.