I would like to generate compile time error for X-macro for all X(a, b) where a > b
/* X(a, b) */
#define LIST \
X(10, 20) \
X(5, 20) \
X(30, 20) \
X(1, 20)
So, generate error for X(30, 20)
Is this possible in C?
EDIT: example usage
For me, left number is for example sizeof of some large struct and right number is fixed space to store this struct. If the struct is bigger then available space, I need compiler to generate error.
//e.g.
X(sizeof(struct conf), 2*PAGE)
Yes, here's a proof of concept:
#pragma push_macro("X")
#undef X
#define X(a,b) typedef int x[(a>b)?-1:1];
LIST
#pragma pop_macro("X")
So, we define X to define a type of array of ints, with either -1 or 1, depending whether a is greater than b. If it is, the array of -1 elements will cause an error.
If using C11, the typedef line can be done using static_assert(a<=b) from assert.h
It is possible in C11 by using the _Static_assert keyword:
#define X( a , b ) _Static_assert( a <= b , "Error!" )
Note that expressions a and b must be constant.
Related
In C I have a define like:
#define VALUE 5
But the user can set a function too:
#define VALUE get_value()
For historical reasons
#define VALUE 0
means "the value is not set, use the default"
The question is how to write an #if that decides if VALUE is 0.
#if VALUE == 0
...
#else
...
#endif
gives "missing binary operator before token "("" error with GCC.
EDIT:
To make the use case clearer:
#if VALUE == 0
set_default_value();
#else
set_value(VALUE)
#endif
So I don't need VALUE to be evaluated in the #if just see if it's literally '0' or not.
You can use preprocessing pattern matching.
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(A,B,...) B
#define GLUE(A,B) GLUE_I(A, B)
#define GLUE_I(A,B) A##B
#define ZERO_TEST(X_) SECOND(GLUE(ZERO_TEST_AGAINST_,X_),0)
#define ZERO_TEST_AGAINST_0 ,1
The key construct here is the SECOND macro, which indirectly expands to its second argument. For pattern matching, you would use this by carefully constructing a first argument; since SECOND normally expands to its second argument, whatever you construct is normally ignored. But since SECOND expands to its second argument indirectly, you can cherry pick a particular pattern by having the first argument expand in particular cases with a comma, which would shove in a new second argument.
In this case we have an indirect paste at the end of ZERO_TEST_AGAINST_, and we're looking for the result of that to be ZERO_TEST_AGAINST_0.
To use this:
#if ZERO_TEST(VALUE)
set_default_value();
#else
set_value(VALUE)
#endif
Demo
http://coliru.stacked-crooked.com/a/2a6afc189637cfd3
Caveat
This fits your spec precisely as given; the indirect paste would not work with this form if you have parenthetical definitions:
#define VALUE (5)
...or:
#define VALUE (get_value() << 2) | 1
...since ZERO_TEST_AGAINST_ and ( do not join to make a valid token.
A generic solution is likely impossible, but you can hack something together:
#define CAT(x, ...) CAT_(x, __VA_ARGS__)
#define CAT_(x, ...) x##__VA_ARGS__
#define CHECK_VALUE_CHECK_0 )(
#define CHECK_VALUE_FALSE(...) CHECK_VALUE_TRUE
#define CHECK_VALUE_TRUE() 1
#define CHECK_VALUE CHECK_VALUE_(CAT(CHECK_VALUE_CHECK_, VALUE))
#define CHECK_VALUE_(...) CHECK_VALUE_FALSE(__VA_ARGS__)
#if CHECK_VALUE
#error Value is 0.
#else
#error Value is not 0.
#endif
Now, if VALUE is defined to 0, the macro CHECK_VALUE will expand to 1. Otherwise it will expand to CHECK_VALUE_TRUE, which as an unknown identifier, is considered falsey by #if.
This solution is hacky:
If VALUE starts with 0,, its causes a hard error.
If VALUE starts with something other than a letter or digit or _ (e.g. (), it causes a hard error.
...
A preprocessor cannot evaluate C-Functions, such as get_value(). It can only handle static data, as its replaced with code prior to compilation, so your statements are not executed at runtime.
if (VALUE == 0) in your C-Code would get replaced for example with if (get_value() == 0) prior to compilation. The Preprocessor is not able to evaluate the return value of get_value() (even if it would always return 0).
A #define VALUE 5 line makes the C preprocessor replace the string VALUE with the string 5 wherever it sees it (outside "strings", that is). The resulting program will not even contain VALUE anymore, and that is what the compiler proper sees(1).
Do an experiment: Get your program (cut it down to a few lines), and run:
cc -E proggie.c > proggie.i
Under Unixy systems you'll get a file proggie.i that contains preprocessed C, which is what the compiler proper sees. No VALUE in sight, and trying to set VALUE in the source ends up as trying to set 0, which obviously won't work.
(1) Historically, C compilers ran a chain of programs over the source (then memories where measured in KiB, not GiB), the first --preprocessor-- was usually called cpp; today's compilers usually don't have a separate preprocessor anymore. But conceptually the first step is still preprocessing the code (handle #include, #if and #defined macros).
I think you're misunderstand how the historical 'the value is not set' works.
In the C preprocessor, whenever you have an #if directive any identifier in the expression that is not an macro (and is not the special function defined) will be replaced by the constant 0 prior to evaluating the #if. So with your example
#define VALUE get_value()
#if VALUE == 0
what happens is the VALUE macro is expanded, then, since there is no get_value macro defined, it is replaced by 0, leaving you with
#if 0() == 0
which gives you the syntax error you see.
I'm trying this for over a week with no success.
I'm creating a logger interface between two processors and I need help with defining automated MACROS.
What do I mean?
Let's say I have a logger message defined as LOGGER_MSG_ID_2 that takes two parameter of uint8 and uint16 types.
I have an enum defined as:
typedef enum{
PARAM_NONE,
PARAM_SIZE_UINT8,
PARAM_SIZE_UINT16,
PARAM_SIZE_UINT32
}paramSize_e;
So LOGGER_MSG_ID_2 will have a bitmap defined as:
#define LOGGER_MSG_ID_2_BITMAP (PARAM_SIZE_UINT16 << 2 | PARAM_SIZE_UINT8)
This bitmap is 1 Byte size, so the maximum number of parameters is 4.
Later on I have a list that defines all parameters type according to message ID:
#define ID_2_P0_TYPE uint8 // first parameter
#define ID_2_P1_TYPE uint16 // 2nd parameter
#define ID_2_P2_TYPE 0 // 3rd parameter
#define ID_2_P3_TYPE 0 // 4th parameter
As I said, I have a limitation of 4 parameters, so I would like to define them and let the MACRO decide weather to use them or not. I defined them as 0 but it can be whatever that works.
I have other MACROS that uses the bitmap to get all kind of attributes, such as number of parameters and message size.
Now it's the tricky part. I want to build a MACRO that creates a bitmap from types. The reason is that I don't want redundancy between the bitmap and parameters definitions.
My problem is that everything I tried failed to compile.
Eventually I would like to have a MACRO such as:
#define GET_ENUM_FROM_TYPE(_type)
that gives me PARAM_SIZE_UINT8, PARAM_SIZE_UINT16 or PARAM_SIZE_UINT32 according to type.
Limitations: I'm using arm compiler on windows (armcl.exe) and C99. I can't use C11 Generic().
I tried the following:
#define GET_ENUM_FROM_TYPE(_type) \
(_type == uint8) ? PARAM_SIZE_UINT8 : \
((_type == uint16) ? PARAM_SIZE_UINT16 : \
((_type == uint32) ? PARAM_SIZE_UINT32 : PARAM_NONE))
Eventually I want to use it like:
#define LOGGER_MSG_ID_2_BITMAP \
(GET_ENUM_FROM_TYPE(ID_2_P3_TYPE) << 6 | \
GET_ENUM_FROM_TYPE(ID_2_P2_TYPE) << 4 | \
GET_ENUM_FROM_TYPE(ID_2_P1_TYPE) << 2 | \
GET_ENUM_FROM_TYPE(ID_2_P0_TYPE))
But when I use it, it doesn't compile.
I have a table of bitmaps:
uint8 paramsSizeBitmap [] = {
LOGGER_MSG_ID_1_BITMAP, /* LOGGER_MSG_ID_1 */
LOGGER_MSG_ID_2_BITMAP, /* LOGGER_MSG_ID_2 */
LOGGER_MSG_ID_3_BITMAP, /* LOGGER_MSG_ID_3 */
LOGGER_MSG_ID_4_BITMAP, /* LOGGER_MSG_ID_4 */
LOGGER_MSG_ID_5_BITMAP, /* LOGGER_MSG_ID_5 */
LOGGER_MSG_ID_6_BITMAP, /* LOGGER_MSG_ID_6 */
LOGGER_MSG_ID_7_BITMAP, /* LOGGER_MSG_ID_7 */
LOGGER_MSG_ID_8_BITMAP, /* LOGGER_MSG_ID_8 */
LOGGER_MSG_ID_9_BITMAP, /* LOGGER_MSG_ID_9 */
LOGGER_MSG_ID_10_BITMAP, /* LOGGER_MSG_ID_10 */
};
And I get this error:
line 39: error #18: expected a ")"
line 39: error #29: expected an expression
(line 39 is LOGGER_MSG_ID_2_BITMAP)
Where do I go wrong?
----- Edit -----
For now I have a workaround that I don't really like.
I don't use uint64 so I made a use of sizeof() MACRO and now my MACRO looks like this:
#define GET_ENUM_FROM_TYPE(_type) \
(sizeof(_type) == sizeof(uint8)) ? PARAM_SIZE_UINT8 : \
((sizeof(_type) == sizeof(uint16)) ? PARAM_SIZE_UINT16 : \
((sizeof(_type) == sizeof(uint32)) ? PARAM_SIZE_UINT32 : PARAM_NONE))
and my paraemters list is:
#define NO_PARAM uint64
#define ID_2_P0_TYPE uint8
#define ID_2_P1_TYPE uint16
#define ID_2_P2_TYPE NO_PARAM
#define ID_2_P3_TYPE NO_PARAM
It works fine but... you know...
I believe the solution is to use concatenation operator ##, and helper defines.
// These must match your enum
#define HELPER_0 PARAM_NONE
#define HELPER_uint8 PARAM_SIZE_UINT8
#define HELPER_uint16 PARAM_SIZE_UINT16
#define HELPER_uint32 PARAM_SIZE_UINT32
// Secondary macro to avoid expansion to HELPER__type
#define CONCAT(a, b) a ## b
// Outer parenthesis not strictly necessary here
#define GET_ENUM_FROM_TYPE(_type) (CONCAT(HELPER_, _type))
With that GET_ENUM_FROM_TYPE(ID_2_P1_TYPE) will expand to (PARAM_SIZE_UINT16) after preprocessing.
Note that suffix in HELPER_*** defines has to match exactly the content of ID_*_P*_TYPE macros. For example HELPER_UINT8 won't work (invalid case). (Thanks #cxw)
The basic problem is that == is not supported for types, only for values. Given
uint8 foo;
you can say foo==42 but not foo == uint8. This is because types are not first class in C.
One hack would be to use the C preprocessor stringification operator # (gcc docs). However, this moves all your computation to runtime and may not be suitable for an embedded environment. For example:
#define GET_ENUM_FROM_TYPE(_type) ( \
(strcmp(#_type, "uint8")==0) ? PARAM_SIZE_UINT8 : \
((strcmp(#_type, "uint16")==0) ? PARAM_SIZE_UINT16 : \
((strcmp(#_type, "uint32")==0) ? PARAM_SIZE_UINT32 : PARAM_NONE)) \
)
With that definition,
GET_ENUM_FROM_TYPE(uint8)
expands to
( (strcmp("uint8", "uint8")==0) ? PARAM_SIZE_UINT8 : ((strcmp("uint8", "uint16")==0) ? PARAM_SIZE_UINT16 : ((strcmp("uint8", "uint32")==0) ? PARAM_SIZE_UINT32 : PARAM_NONE)) )
which should do what you want, although at runtime.
Sorry, this doesn't directly answer the question. But you should reconsider this whole code.
First of all, _Generic would have solved this elegantly.
The dirty alternative to untangle groups of macros like these, would be to use so-called X macros, which are perfect for cases such as "I don't want redundancy between the bitmap and parameters definitions". You can likely rewrite your code with X macros and get rid of a lot of superfluous defines and macros. How readable it will end up is another story.
However, whenever you find yourself this deep inside some macro meta-programming jungle, it is almost always a certain indication of poor program design. All of this smells like an artificial solution to a problem that could have been solved in much better ways - it is a "XY problem". (not to be confused with X macros :) ). The best solution most likely involves rewriting this entirely in simpler ways. Your case doesn't sound unique in any way, it seems that you just want to generate a bunch of bit masks.
Good programmers always try to make their code simpler, rather than making it more complex.
In addition, you may have more or less severe bugs all over the code, caused by the C language type system. It can be summarized as:
Bit shifts or other bitwise arithmetic should never be used on signed types. Doing so can lead to all manner of subtle bugs and poorly-defined behavior.
Enumeration constants are always of type int which is signed. You should avoid mixing them with bitwise arithmetic. Avoid enums entirely for programs like this.
Small integer types such as uint8_t or uint16_t get implicitly type promoted to int when used in an expression. Meaning that the C language will bandwagon most of your attempts to get the correct type and replace everything with int anyway.
The resulting type of your macros will be int, which is not what you want.
I have addressing macros (it's on a microcontroller, so accessing physical address is OK) that break down to this (after a long sequence of conditional defines, attributes, etc):
#define ADDR_A (*18)
#define ADDR_B (*30)
#define ADDR_C (*18)
I would like to compare them so I can optimize the compilation:
#if ADDR_A==ADDR_C
return 1;
#else
return 0;
#endif
But I get "error: operator '*' has no left operand" which makes sense. Is it possible to compare the DEFINITIONS of macros. I have a hunch I could convert them to string somehow to compare, but I haven't found a way (like with the # for a macro argument).
And no, I'm not looking to do this at runtime as I'm counting the cycles.
You can't compare strings in an #if, because:
you can only use #if with constant expressions
strings can only be compared using a loop or a function
loops aren't constant expressions
and:
Constant expressions shall not contain assignment, increment, decrement, function-call,
or comma operators, except when they are contained within a subexpression that is not
evaluated. (C11, 6.6P3)
The best I can think of is to split up the addresses and the dereferencing into two different macros, like:
#define ADDR_A (18)
#define ADDR_B (30)
#define ADDR_C (18)
#define GET_A (*ADDR_A)
#define GET_B (*ADDR_B)
#define GET_C (*ADDR_C)
#if ADDR_A == ADDR_B
return 1
#else
return 0
#endif
Note that checking the equality of constants "at runtime" will be elided by pretty much any compiler worth its salt; in this example, the compiler just generates the equivalent of return 1 because it knows at compile-time that the condition will evaluate to false; counting cycles is a red herring here, because these comparisons will be elided.
Also, for what it's worth, I'm not sure how you're using those macros (I can't construct an example in my head where they would be syntactically valid), but I have a feeling your code would be easier to understand if you just made your macros contain the addresses and you dereference those addresses inline in your code. Were I reading your code, I would much prefer:
#define ADDR_A (18)
#define ADDR_B (30)
#define ADDR_C (18)
if (ADDR_A == ADDR_B)
return 1
return 0
How about putting only the addresses in the macros, and the type information separately?
#define ADDR_A (18)
#define ADDR_B (30)
#define ADDR_C (18)
unsigned uint16_t *A = (uint16_t*)ADDR_A;
unsigned uint16_t *B = (uint16_t*)ADDR_B;
unsigned uint16_t *C = (uint16_t*)ADDR_C;
Then you can use your tests.
Alternatively, skip the preprocessor, and just do it in C:
unsigned uint16_t *const A = (uint16_t*)18;
unsigned uint16_t *const B = (uint16_t*)30;
unsigned uint16_t *const C = (uint16_t*)18;
int f()
{
if (A == C)
return 1;
else
return 0;
}
Unless you have an extremely low-quality compiler, you can expect it to recognise A==C as a constant expression and simplify the code accordingly.
I am looking at a math.h header included in my IDE. I am seeing the following code that is syntax I don't understand. This is basic stuff but can someone explain to me how this works?
#define isgreater(x,y) \
(__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \
!isunordered(__x,__y) && (__x > __y);}))
So for example what does it do when you start something with double underscore eg: __typeof
Is that to allow for undefined sizes? so this macro can take values of different sizes?
Is the slash just to span line breaks in the source?
what does __extension__ do?
thanks
You are seeing the use of a few compiler extensions:
__typeof__ is a GCC extension that lets you get the type of the variable (and use it in a variable declaration); it is there so that the macro can handle whatever type x and y are.
The second GCC extension turns ({ ... }) into an expression that evaluates to the value of the last statement inside it; this lets you declare variables inside this block, which is for the purpose of avoiding evaluating the two operands x and y twice. The results of x and y (which could be something like i++ which you don't want to evaluate twice) are stored in two temporary variables __x and __y and then those two temporary variables are used instead of x and y to avoid double evaluation.
__extension__ is an extension that suppresses the warning you'd otherwise get about using the above extension.
And yes, the \ just makes the definition of the macro span multiple lines (\ joins lines together and is done very early in the compilation process, even before the macros and preprocessor definitions get looked at).
The whole point of this rigmarole is to avoid evaluating x and y twice. If you did
bool g = isgreater(x++, y++);
And you didn't use that trick, you'd get
bool g = !isunordered(x++, y++) && (x++ > y++);
Which would cause x and y to be incremented twice each instead of just once like you intended. Instead, with the trick, you get something like (using better names for the temporary variables)
int tmpx = x++;
int tmpy = y++;
bool g = !isunordered(tmpx, tmpy) && (tmpx > tmpy);
(if x and y are integers) which is correct and avoids double incrementation. This goes for other things as well, such as function calls:
isgreater(launch_missiles(3), launch_missiles(4));
Without the trick, you'd end up launching 14 missiles instead of 7, which would be catastrophic.
This reformatting of the definition may help you
#define isgreater(x,y) \
( \
__extension__ ( \
{ \
__typeof__(x) __x = (x); \
__typeof__(y) __y = (y); \
!isunordered(__x,__y) && (__x > __y); \
} \
) \
)
__extension__ marks code which uses gcc extensions to standard ANSI C. The extension in this case is the __typeof__ operator which provides the type of a variable at compile time, and it is used to declare __x and __y with the same types as x and y. It then goes ahead and checks that the pair of values are both ordered (isunordered is a Math library function) and __x is greater than __y.
I want to make a simple macro with #define for returning the smaller of two numbers.
How can i do this in C ? Suggest some ideas, and see if you can make it more obfuscated too.
Typically:
#define min(a, b) (((a) < (b)) ? (a) : (b))
Be warned this evaluates the minimum twice, which was the reason for disaster in a recent question.
But why would you want to obfuscate it?
This one stores the result in a variable, and only evaluates each argument once. It's basically a poor-mans inline function + declaration:
#define min(t, x, a, b) \
t x; \
{ \
t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
x = _this_is_a_unique_name_dont_use_it_plz_0_ < \
_this_is_a_unique_name_dont_use_it_plz_1_ ? \
_this_is_a_unique_name_dont_use_it_plz_0_ : \
_this_is_a_unique_name_dont_use_it_plz_1_ ; \
}
Use it like:
min(int, x, 3, 4)
/* x is an int, equal to 3
Just like doing:
int x = min(3, 4);
Without double evaluation.
*/
And, just for the hell of it, a GNU C example:
#define MAX(a,b) ({ \
typeof(a) _a_temp_; \
typeof(b) _b_temp_; \
_a_temp_ = (a); \
_b_temp_ = (b); \
_a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
})
It's not obfuscated, but I think this works for any type, in any context, on (almost, see comments) any arguments, etc; please correct if you can think of any counterexamples.
Sure, you can use a #define for this, but why would you want to? The problem with using #define, even with parentheses, is that you get unexpected results with code like this (okay, you wouldn't actually do this, but it illustrates the problem).
int result = min(a++, b++);
If you're using C++ not C, surely better to use an inline function, which (i) avoids evaluating the parameters more than once, and (ii) is type safe (you can even provide versions taking other types of value, like unsigned, double or string).
inline int min(int a, int b) { return (a < b) ? a : b; }
I think this method is rather cute:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
I want to make a simple macro with #define for returning the smaller of two numbers.
I wanted to add a solution when the numbers are floating point.
Consider when the numbers are floating point numbers and one of the numbers is not-a-number. Then the result of a < b is always false regardless of the value of the other number.
// the result is `b` when either a or b is NaN
#define min(a, b) (((a) < (b)) ? (a) : (b))
It can be desirable that the result is as below where "NaN arguments are treated as missing data". C11 Footnote #242
a NaN | b NaN | a < b | min
-------+---------+---------+---------------
No | No | No | b
No | No | Yes | a
No | Yes | . | a
Yes | No | . | b
Yes | Yes | . | either a or b
To do so with a macro in C would simple wrap the fmin() function which supprts the above table. Of course code should normally used the fmin() function directly.
#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))
Note that fmin(0.0, -0.0) may return 0.0 or -0.0. They both have equal value.
If I were just trying to lightly obfuscate this I would probably go with something like:
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
I think Doynax's solution is pretty cute, too. Usual reservations for both about macro arguments being evaluated more than once.
For slightly obfuscated, try this:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
Basically, it subtracts them, and looks at the sign-bit as a 1-or-0.
If the subtraction results in a negative number, the first parameter is smaller.