I have a macro that performs splitting and checks alignment.
#define BYTES_TO_WORDS(x) ((CHECK_ALIGNMENT(x,2)) * ((x) / 2))
I would like to implement CHECK_ALIGNMENT as a macro that always returns 1 and throws an error if x does not divide by 2.
The BYTES_TO_WORDS macro BYTES_TO_WORDS called from different contexts, sometimes with x as a constant integer expression of compilation time, and another time with x as an integer expression that is allowed at runtime.
Is it possible to implement CHECK_ALIGNMENT so that it static_assert when the macro is invoked with a constant expression, and some execution check at runtime when the expression is not a compile-time constant?
I can change macro definitions, but not a way to call and use a macro.
Here is a possible solution (this does not always work):
#define CHECK_ALIGNMENT(x,alignedTo) (1/(((alignedTo)-((x)%(alignedTo)))/(alignedTo)))
In this implementation, we should get a Division By Zero error at runtime or compile time, depending on the input.
However, this does not always work due to a compiler error. Also, the error message is not very nice.
A better solution would be to determine if the parameter is a compile-time constant and uses static_assert in this case with a good compile-time error message. If the parameter is not a compile time constant, check alignment at run time.
Is it possible?
I need this to work with Visual Studio 2015.
Explanation
There are comments in the comments about why I use macros in a C ++ question.
The macro BYTES_TO_WORDS is located in the header file, which is included in various tools, the C ++ compiler is one of them.
Other tools use this macro and evaluate the arithmetic expression ((x) / 2) , but on these tools I define CHECK_ALIGNMENT - 1 because they are not able to handle constexpr , templates, or even function calls.
When compiling this header with a C ++ compiler, I would like to point CHECK_ALIGNMENT to something else that will cause a static_assert or a runtime error if necessary.
The definition of CHECK_ALIGNMENT can be any C ++ 11 code (or C ++ 14, which is supported by VS2015), it can use patterns, constexpr or whatnot.