Preprocessor Directive: #elif not defined? - c-preprocessor

Is there a preprocessor directive that checks whether a constant is not defined. I am aware of the #ifndef directive but I am also looking for a #elif not defined directive. Does #elif not defined exist?
This is how I would use it:
#define REGISTER_CUSTOM_CALLBACK_FUNCTION(callbackFunctName) \
#ifndef CUSTOM_CALLBACK_1 \
#define CUSTOM_CALLBACK_1 \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName) \
#elif not defined CUSTOM_CALLBACK_2 \
#define CUSTOM_CALLBACK_2 \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName) \
#elif not not defined CUSTOM_CALLBACK_3 \
#define CUSTOM_CALLBACK_3 \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName) \
#endif

How about the
#elif !defined(...)
But you've got bigger problems - the trailing \ exclude the other directives - or rather make them illegal. So, even with the valid syntax, your definitions won't do what you want.
You'll need to move the initial define inside the conditions.
#ifndef CUSTOM_CALLBACK_1
#define CUSTOM_CALLBACK_1
#define REGISTER_CUSTOM_CALLBACK_FUNCTION(callbackFunctName) \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName)
#elif !defined(CUSTOM_CALLBACK_2)
//.....

Related

Define a preprocessor macro with preprocessor comands

I'm using often a syntax like
#ifdef __cplusplus
extern "C"
#endif
void myCFunc();
so I tried to make a macro to have a syntax like
CFUNC(void myCFunc());
I'm not relly sure if it's something that can be done (can preprocessor execute its freshly generate code?)
The failed idea was something like
#define CFUNC(ARGUMENT) \
#ifdef __cplusplus \
extern "C" \
#endif \
ARGUMENT;
Is there a way make a macro that generates code for the preprocessor?
Thanks
You can define two different macros depending on the context:
#ifdef __cplusplus
#define CFUNC(ARGUMENT) extern "C" ARGUMENT;
#else
#define CFUNC(ARGUMENT) ARGUMENT;
#endif
CFUNC(FOO)
However, the common way to do this is the following. It includes the braces and can be used both in definitions and declarations.
#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif
EXTERN_C
void foo(void) { ... }
EXTERN_C_END
You can inverse #define and #ifdef:
#ifdef __cplusplus
#define CFUNC(ARGUMENT) \
extern "C" \
ARGUMENT;
#else
#define CFUNC(ARGUMENT) ARGUMENT;
#endif

purpose of error injection macro in linux kernel

I have seen a macro ALLOW_ERROR_INJECTION which is used in SYSCALL_DEFINEx
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
/*
* Whitelist ganerating macro. Specify functions which can be
* error-injectable using this macro.
*/
#define ALLOW_ERROR_INJECTION(fname, _etype) \
static struct error_injection_entry __used \
__attribute__((__section__("_error_injection_whitelist"))) \
_eil_addr_##fname = { \
.addr = (unsigned long)fname, \
.etype = EI_ETYPE_##_etype, \
};
#else
#define ALLOW_ERROR_INJECTION(fname, _etype)
#endif
#endif
Can anyone provide me enough documentation on this.
What is the use of it. What is whitelist

How to define macro bases on macro value?

I have macros:
#if defined DEBUG && DEBUG
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
Which effectively do nothing when DEBUG has TRUE value.
But now I want to provide the TYPE thing. Which will show the type of debugging:
D( 1, "some string" );
D( 2, "another thing" );
Is there a way to define such macros which will do nothing for D(1,..) and print debug messages for D(2,...) when DEBUG is 2 and viceversa when 1?
I wanna something like this::
#if defined DEBUG && DEBUG
# define D(type,...) if DEBUG&type THEN printf(__VA_ARGS__) else do nothing
#else
# define D(...)
#endif
Well, it won't be truely evaluated at preprocessing time, but if the type is a compile-time-constant, still at compile-type.
#define D(type, ...) (void)((type & DEBUG) && fprintf(stderr, __VA_ARGS__))
The above needs at least C99 though.
You can do it like this;
#if defined DEBUG
# define P1(...)
# define P2(...) printf(__VA_ARGS__)
# define D(n, ...) P##n(__VA_ARGS__)
#else
# define D(...)
#endif
main()
{
D(1, "Test");
D(2, "Test2");
}
This did not resolve the problem but take me closer. Maybe it will be useful for someone:
#define _CAT(a, ...) a ## __VA_ARGS__
#define CHECK(...) SECOND(__VA_ARGS__, 0)
#define SECOND(x, n, ...) n
#define _NOT_0 _TRUE()
#define _TRUE() ~, 1
#define BOOL(x) NOT(NOT(x))
#define NOT(x) CHECK(_CAT(_NOT_, x))
#define IF(cond) _IF(BOOL(cond))
#define _IF(cond) _CAT(_IF_, cond)
#define _IF_1(...) __VA_ARGS__
#define _IF_0(...)
IF(1)(printf("YES\n");)
IF(0)(printf("NO\n");)
Links to tricks: first and second. Second link is more interesting because it describes what is coming on step-by-step

How to enable custom TRACE macro for specific files only?

I wrote the following trace macro in a file named "debug.h".
#define TRACE(x) \
printf( \
"%s(%d): ", \
__FILE__, \
__LINE__ \
); \
\
printf(x);
In debug I'd like to enable the macro only for certain files since resources are limited on the platform that I'm using. I don't want to completely remove the TRACE calls from the files. Just disable them.
Is there a clean way to do this in C using the preprocessor?
In debug.h:
#if TRACE_ENABLE
#define TRACE(x) \
printf( \
"%s(%d): ", \
__FILE__, \
__LINE__ \
); \
\
printf(x);
#else
#define TRACE(x)
#endif
Then, in your source files where you don't want trace:
#define TRACE_ENABLE 0
#include "debug.h"
or just:
#include "debug.h"
In source files to enable trace:
#define TRACE_ENABLE 1
#include "debug.h"
While both answers seems good to me, I think Giuseppe's answer is more useful most of the time since if you use this macro many times in a file, and you want to switch debug on/off for complete files, pmg's method is exhausting.
The important thing is to not forget adding the else statement: #else TRACE(X); if you want to edit it in the specific file and not in header, use:
#ifdef TRACE
#undef TRACE
#endif
#define TRACE(X)
A trick I've used somtimes is the use of a bit mask to enable a subset of the files whete the TRACE is used:
File1.c:
#if TRACE_MASK & 0x01
#define TRACE(x) ...
#endif
File2.c:
#if TRACE_MASK & 0x02
#define TRACE(x) ...
#endif
...
Then you can define your TRACE_MASK macro in the preprocessing options: /DTRACE_MASK=0x03 to enable the trace on both File1.c and File2.c
The only problem is that there is a limited numner of bits... (but you can use more than one macro: TRACE_MASK1, TRACE_MASK2...)
Bye
EDIT: of course you can write tdefinition once in a file "trace.h", and just redefine the mask in each source:
File trace.h:
#if TRACE_MASK & TRACE_CURRENT
#define TRACE(x) ...
#else
#define TRACE(x) do {} while(0)
#endif
File1.c:
#define TRACE_CURRENT 0x01
#include "trace.h"
File2.c:
#define TRACE_CURRENT 0x02
#include "trace.h"
What about
#define TRACE(x, y) do if (y) {/*your prints*/} while (0)
and also
#define TRACE_ENABLE 1
or
#define TRACE_ENABLE 0
at the top of your sources.
Then replace the TRACE invocations with
TRACE(foo, TRACE_ENABLE);

How to eliminate a redundant macro parameter

A while ago, I wrote a set of X-macros for a largish project. I needed to maintain coherent lists of both strings and enumerated references/hash values/callback functions etc. Here is what the function callback looks like
#define LREF_LOOKUP_TABLE_TEXT_SIZE 32
#define _LREF_ENUM_LIST(_prefix,_ref,...) _prefix ## _ ## _ref,
#define _LREF_BASE_STRUCT_ENTRY(_prefix,_ref) .text= #_ref "\0", .position= _LREF_ENUM_LIST(_prefix, _ref)
#define _LREF_FUNCTION_STRUCT_LIST(_prefix,_ref,...) {_LREF_BASE_STRUCT_ENTRY(_prefix,_ref) _prefix ## _ ## _ref ## _callback},
#define _LREF_ENUM_TYPEDEF(_prefix) \
typedef enum _prefix \
{ \
_ ## _prefix ## s(_prefix,_LREF_ENUM_LIST) \
_LREF_ENUM_LIST(_prefix,tblEnd) \
} e_ ## _prefix
#define _LREF_LOOKUP_TABLE_TYPEDEF(_prefix, _extras) \
typedef struct _prefix ## _lookup \
{ \
const char text[LREF_LOOKUP_TABLE_TEXT_SIZE]; \
e_ ## _prefix position; \
_extras \
} _prefix ##_lookup_t
#define LREF_GENERIC_LOOKUP_TABLE(_prefix, _type, _tabledef, _listdef, _extras) \
_LREF_ENUM_TYPEDEF(_prefix); \
_LREF_LOOKUP_TABLE_TYPEDEF(_prefix,_tabledef); \
_extras \
_LREF_LOOKUP_TABLE_DECLARATION(_prefix,_listdef, _type)
#define LREF_FUNCTION_LOOKUP_TABLE(_prefix, _type) \
_ ## _prefix ## s(_prefix, _LREF_FUNCTION_DEF ) \
LREF_GENERIC_LOOKUP_TABLE( _prefix, \
_type, \
void* (*function) (void*);, \
_LREF_FUNCTION_STRUCT_LIST, )
This sits in a header file and allows me to write things like:
#define _cl_tags(x,_) \
_(x, command_list) \
_(x, command) \
_(x, parameter) \
_(x, fixed_parameter) \
_(x, parameter_group) \
_(x, group) \
_(x, map) \
_(x, transform)
LREF_FUNCTION_LOOKUP_TABLE(cl_tag, static);
This keeps processing routines short. For example, loading a configuration file with the above tags is simply:
for (node_tag = cl_tag_lookup_table; node_tag->position != cl_tag_tblEnd; node_tag++)
{
if (strcasecmp(test_string, node_tag->text) == 0)
{
func_return = node_tag->function((void*)m_parser);
}
}
My question is this: I hate that I have to include the second parameter in my #define. I want to be able to write #define _cl_tags(_) instead of #define _cl_tags(x,_). As you can see, the x is only used to pass the prefix (cl_tag) down. But this is superfluous as the prefix is a parameter to the initial macro.
The solution to this would be easy if my preprocessor would expand the outer-most macros first. Unfortunately, GCC's preprocessor works through the inner-most macros, i.e. parameter values, before expanding the outermost macro.
I am using gcc 4.4.5
Clarification
By C89 (and C99) standard, the following definitions
#define plus(x,y) add(y,x)
#define add(x,y) ((x)+(y))
with the invocation
plus(plus(a,b),c)
should yield
plus(plus(a,b),c)
add(c,plus(a,b))
((c)+(plus(a,b))
((c)+(add(b,a))
((c)+(((b)+(a))))
gcc 4.4.5 gives
plus(plus(a,b),c)
plus(add(b,a),c)
plus(((b)+(a)),c)
add(c,((b)+(a)))
((c)+(((b)+(a))))
Here's what I would do (have done similarly):
Put these in a utility header file:
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
Then define this before including your LREF macro header file:
#define LREF_TAG cl_tag
Then, in your LREF macro header file,
#define LREF_PFX(x) PPCAT(LREF_TAG, x)
#define LREF_SFX(x) PPCAT(x, LREF_TAG)
Then replace every instance of _prefix ## foo with LREF_PFX(foo) and foo ## _prefix with LREF_SFX(foo).
(When pasting more than two tokens together, just use nested PPCAT's.)
Your invocation would become
#define LREF_TAG cl_tag
#define _cl_tags(_) \
_(command_list) \
_(command) \
_(parameter) \
_(fixed_parameter) \
_(parameter_group) \
_(group) \
_(map) \
_(transform)
LREF_FUNCTION_LOOKUP_TABLE(static);
This answer just addresses the 'clarification'. Here is the correct behaviour:
#define plus(x,y) add(y,x)
#define add(x,y) ((x)+(y))
Initial: plus(plus(a,b),c)
Pass 1a: plus(add(b,a),c)
Pass 1b: add(c,add(b,a))
Pass 2a: add(c,((b)+(a)))
Pass 2b: ((c)+(((b)+(a))))
The rules are that each macro is replaced once non-recursively (starting from the inner-most when they are nested); and then a new pass (aka. "rescan") happens repeating the same procedure, this continues until a pass performs no replacement.
I'm not sure what point you were trying to make though, as you give the same final conclusion for both GCC and what you expected to happen.

Resources