The C define with any value for non zero - c

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.

Related

Asking a predefined value as a float(or string) on an `#if` macro

I want to condition in an #if on the float(or string) value of a predefined variable.
As I saw if the value of the predefined variable is a whole number the #if is working good. But, if it is a float or a string, the if is not working as expected.
For example:
#define _VER_ = 103
#if _VER_ == 103
//Do somthing
#endif
The above code is working as expected, the #if becomes active/not active according to the _VER_ value. But, if the _VER_ value will be set to 1.0.3 or to "1.0.3" the #if is not working as expected.
For example:
#define _VER_ = 1.0.3
#if _VER_ == 1.0.3
//Do somthing
#endif
Or this:
#define _VER_ = "1.0.3"
#if _VER_ == "1.0.3"
//Do somthing
#endif
Both code example are not working as expected, the #if stays inactive regardless with the _VER_ value.
How to make this working properly?
The pre-processor is not able to do string comparisons at all, and floating point values in #if directives are not supported by the standard either. But even if they were comparing floating point is always critical due to rounding issues (keep in mind that you cannot even represent many of such simple numbers like 0.1 exactly as they are periodic in binary), see e.g. here or here, thus you cannot compare floating points safely either (most likely that's why they are not supported...).
What you could do, though, is having three distinct integral values:
#define MAJOR 1
#define MINOR 0
#define REVISION 3
Now you can do comparisons on these single values individually like:
#if MAJOR > 1 || MAJOR == 1 && MINOR > 0
// anything after 1.0.x
What you could do as well is combining these values into a single integer value by shifting them appropriately, e. g.
#define VERSION MAKE_VERSION(MAJOR, MINOR, REVISION)
#define MAKE_VERSION(X, Y, Z) MAKE_VERSION_(X, Y, Z)
// intermediate step necessary to resolve the version parts correctly
#define MAKE_VERSION_(X, Y, Z) (X ## lu << 16 | Y ## lu << 8 | Z ## lu)
Adding lu suffixes: long is guaranteed large enough by the standard such that shifting by 16 bit will fit into the type (which is not guaranteed for int!). You might experiment with other offsets to make the result fit into int and then leaving out the suffix (e. g. shifting by 8 or 12 instead of 16) or to allow more sub-versions (e. g. by shifting by 20 instead of 16).
Multiplying by 10000 and 100 would do the trick as well and result in more human readable version numbers (in decimal notation at least).
Finally you could create a version string by another macro:
#define VERSION_STRING MAKE_VERSION(MAJOR, MINOR, REVISION)
#define MAKE_VERSION(X, Y, Z) MAKE_VERSION_(X, Y, Z)
// intermediate step needed for correct stringification
#define MAKE_VERSION_(X, Y, Z) #X "." #Y "." #Z
Side note:
#define _VER_ = 103
Is plain wrong for two reasons:
The pre-processor does nothing else than pure text processing, it is not aware of any C code. The assignment sign (=) will be included in text replacement anywhere you use it (so #if _VER_ == 103 will be expanded to #if = 103 == 103).
Identifiers starting with an underscore followed by a capital character are reserved, using them results in undefined behaviour (note: identifiers with two subsequent underscores – anywhere – as well).
You can split the version up in the way that makes most sense anyway, namely:
#define VERS_MAJOR 1
#define VERS_MINOR 0
#define VERS_PATCH 3
And then do pre-processor comparisons such as:
#if (VERS_MAJOR == 1) && (VERS_MINOR == 0)
...
If you need to get 1.0.3 as output then convert it to a string literal:
#define STR(x) #x
#define STR_VERSION(a,b,c) STR(a) "." STR(b) "." STR(c)
#define VERSION STR_VERSION(VERS_MAJOR,VERS_MINOR,VERS_PATCH)
...
puts(VERSION); // prints 1.0.3

Defining #if preprocessor condition in C

I wanted to define a compile time input validity checker for the library I am developing. So I thought maybe #define a function like #if preprocessor in C which is going to be compiled with GCC, something link this:
#define VALIDITY_CHECK(x) {#if (x)>10
#error "input out of range"
#endif}
But it doesn't work. So what is the proper way of writing such compile time validity checker?
You can use a trick that provokes a compile time error if a condition is not met:
#define ASSERT(condition) (void)(sizeof (struct { int:-!(condition); }))
#define x1 23
#define x2 42
void f(void) {
ASSERT(x1 < 31);
ASSERT(x1 > 31);
ASSERT(x2 < 31);
ASSERT(x2 > 31);
}
It works by evaluating the condition by the !-operator as 1 for false and 0 for true. This number is used to declare an anonymous bit field of size -1 or 0, respectively, in a struct. The anonymous struct is just used for the sizeof operator, and the result is discarded as an unused expression.
Since a negative bit field size is not allowed, the compiler will output a diagnostic message, if the condition is not met.
If the condition is met, the compiler will happily optimize the unused expression away and generate no code for the line.
You could augment the ASSERT() by a comment behind it, if necessary. The diagnostic message will show it.
ASSERT(x1 < 31); // Bla bla bla
You can’t have macro directives in the value of a #define. This is because the # in a value is the "stringizing" operator and it must be followed by a macro argument.
In the #define value, you can thus have #x because x is the argument of VALIDITY_CHECK, but you can’t have #if, #error, or #endif.
You are forced to write the following code explicitly everywhere.
#if (x)>10
#error "input out of range"
#endif

Macro to replace undefined tokens with some predefined value

Macro to replace undefined tokens with some predefined value.
I would like to have some EXPAND(x) macro that will expand to x if x is defined and to, for example, -1 if it is not, so that this code:
#define M1 1
#define M2 2
#undef M3
#define M4 (2*2)
printf("%i %i %i %i", EXPAND(M1), EXPAND(M2), EXPAND(M3), EXPAND(M4));
would print:
1 2 -1 4
Is that possible in C? Only thing that I can think of is to stringify x and then parse it with constexpr function, but that will work only in simple cases.
The only way to do this would be to use some header file that knows all possible macros and checks if they are defined. If not, replace them with -1.
#ifndef M1
#define M1 -1
#endif
#ifndef M2
#define M2 -1
#endif
...
You would then include this header after the file containing the macros/after the macro defines.
Though please note that this is a bad design, full of tight coupling and other incredibly bad ideas. There's certainly better ways to solve the actual problem, like ensuring that the code won't compile if a certain macro is missing.

MACRO that converts enum to type in c

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.

Can the C preprocessor perform integer arithmetic?

As the questions says, is the C preprocessor able to do it?
E.g.:
#define PI 3.1416
#define OP PI/100
#define OP2 PI%100
Is there any way OP and/or OP2 get calculated in the preprocessing phase?
Integer arithmetic? Run the following program to find out:
#include "stdio.h"
int main() {
#if 1 + 1 == 2
printf("1+1==2\n");
#endif
#if 1 + 1 == 3
printf("1+1==3\n");
#endif
}
Answer is "yes", there is a way to make the preprocessor perform integer arithmetic, which is to use it in a preprocessor condition.
Note however that your examples are not integer arithmetic. I just checked, and gcc's preprocessor fails if you try to make it do float comparisons. I haven't checked whether the standard ever allows floating point arithmetic in the preprocessor.
Regular macro expansion does not evaluate integer expressions, it leaves it to the compiler, as can be seen by preprocessing (-E in gcc) the following:
#define ONEPLUSONE (1 + 1)
#if ONEPLUSONE == 2
int i = ONEPLUSONE;
#endif
Result is int i = (1 + 1); (plus probably some stuff to indicate source file names and line numbers and such).
The code you wrote doesn't actually make the preprocessor do any calculation. A #define does simple text replacement, so with this defined:
#define PI 3.1416
#define OP PI/100
This code:
if (OP == x) { ... }
becomes
if (3.1416/100 == x) { ... }
and then it gets compiled. The compiler in turn may choose to take such an expression and calculate it at compile time and produce a code equivalent to this:
if (0.031416 == x) { ... }
But this is the compiler, not the preprocessor.
To answer your question, yes, the preprocessor CAN do some arithmetic. This can be seen when you write something like this:
#if (3.141/100 == 20)
printf("yo");
#elif (3+3 == 6)
printf("hey");
#endif
YES, I mean: it can do arithmetic :)
As demonstrated in 99 bottles of beer.
Yes, it can be done with the Boost Preprocessor. And it is compatible with pure C so you can use it in C programs with C only compilations. Your code involves floating point numbers though, so I think that needs to be done indirectly.
#include <boost/preprocessor/arithmetic/div.hpp>
BOOST_PP_DIV(11, 5) // expands to 2
#define KB 1024
#define HKB BOOST_PP_DIV(A,2)
#define REM(A,B) BOOST_PP_SUB(A, BOOST_PP_MUL(B, BOOST_PP_DIV(A,B)))
#define RKB REM(KB,2)
int div = HKB;
int rem = RKB;
This preprocesses to (check with gcc -S)
int div = 512;
int rem = 0;
Thanks to this thread.
Yes.
I can't believe that no one has yet linked to a certain obfuscated C contest winner. The guy implemented an ALU in the preprocessor via recursive includes. Here is the implementation, and here is something of an explanation.
Now, that said, you don't want to do what that guy did. It's fun and all, but look at the compile times in his hint file (not to mention the fact that the resulting code is unmaintainable). More commonly, people use the pre-processor strictly for text replacement, and evaluation of constant integer arithmetic happens either at compile time or run time.
As others noted however, you can do some arithmetic in #if statements.
Be carefull when doing arithmetic: add parenthesis.
#define SIZE4 4
#define SIZE8 8
#define TOTALSIZE SIZE4 + SIZE8
If you ever use something like:
unsigned int i = TOTALSIZE/4;
and expect i to be 3, you would get 4 + 2 = 6 instead.
Add parenthesis:
#define TOTALSIZE (SIZE4 + SIZE8)

Resources