I have macro that performs a division 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 triggers an error if x
does not divide by 2.
The macro BYTES_TO_WORDS
is called from different contexts, sometimes with x
as a compile-time constant integer expression and other times with x
as an integer expression that is resolved on runtime.
Is it possible to implement CHECK_ALIGNMENT
such that it would perform static_assert
when the macro is called with constant expression, and some runtime error check when the expression is not a compile-time constant?
I can change the macro definitions, but not the way the macro is called and used.
Here is a possible solution (that doesn't always work):
#define CHECK_ALIGNMENT(x,alignedTo) (1/(((alignedTo)-((x)%(alignedTo)))/(alignedTo)))
In this implementation we should get Division By Zero error on either runtime or compile time, depends on the input.
However this does not always work due to a compiler bug.
Also, the error message is not very nice.
A better solution would be identifying whether the parameter is a compile time constant and using static_assert
in such case, with a nice compile time error message. If the parameter does not represent a compile time constant, then check the alignment on runtime.
Is this possible?
I need this to work on Visual Studio 2015.
Clarification
There are some discussions in the comments regarding to why I'm using macros in C++ question.
The BYTES_TO_WORDS
macro is in a header file which is included by various tools, 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
to 1 as they are not capable of handling constexpr
, templates or even function calls.
When compiling this header with C++ compiler I would like to define CHECK_ALIGNMENT
to something else, that would either trigger static_assert
or runtime error when needed.
The definition of CHECK_ALIGNMENT
can be any C++11 code (or C++14 that is supported by VS2015), can use templates, constexpr or whatnot.