Consider the snippet:
#define CAT(a, b) a##b
#define M_0 CAT(x, y)
#define M(a) CAT(M_, a)()
M(0);
#define N_0() CAT(x, y)
#define N(a) CAT(N_, a)()
N(0);
To me both definitions of M(a) and N(a) look identical.
However, cpp of GCC 4.6.1 expands this to:
CAT(x, y)();
xy;
Why?
#define M_0 CAT(x, y)
#define N_0() CAT(x, y)
M_0 is a simple text replacement. N_0 is a macro function that, when being evaluated, evaluates any other macro functions as necessary.
Related
I have following code snippet
#define DEBUG_PRINT( x, fmt, args... ) if (DEBUG_##x || x == 0) {fprintf(fmt, ##args);} else;
Where x is the verbosity level.
I want to execute the fprint statement if verbosity x is 0 and when corresponding DEBUG_##x is defined
While compiling an error is throwing as DEBUG_1 is undefined.
My use case is to skip the fprint statement if DEBUG_1 is not defined. Help me crack this logic
You don't even need a regular if. You can use preprocessor to completely remove printf if the macro is not defined:
#define CAT(x, y) CAT_(x, y)
#define CAT_(x, y) x##y
#define TRUTHY_X ,
#define TRUTHY_1X ,
#define RUN_IF(cond, then) RUN_IF_A(CAT(CAT(TRUTHY_, cond), X) then,)
#define RUN_IF_A(...) RUN_IF_B(__VA_ARGS__)
#define RUN_IF_B(cond, then, ...) then
#define DEBUG_PRINT(x, fmt, ...) RUN_IF(CAT(DEBUG_,x),printf(fmt, ##__VA_ARGS__));
This assumes that DEBUG_x is defined to either an empty string or 1. This also assumes that DEBUG_ and some other things are not defined.
I didn't add the special treatment for x == 0, but that can be solved with #define DEBUG_0.
Is there a way to use only one define statement for this header, without changing the function-like macro into a function?
my.h file:
#ifndef MY_H
#define MY_H
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#endif
For example, I was able to do the following for a constant:
pi.h file:
#ifndef PI
#define PI 3.14159
#endif
I also am aware of the warnings in regards to using function-like macros from posts like:
https://stackoverflow.com/a/15575690/4803039
I just want to see if there is a more optimal/refactored way. It just seems weird to include an additional #define statement that defines the rest of the header body, when the header body only includes a #define statement itself.
This is what you want:
#ifndef MIN
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#endif
Your approach would be fine - it's sufficient to guard against doubly defining macro. Adding a definition guard is usually useful if you want to protect an entire file. This serves to both shorten the code (as you don't have to guard each macro independently) and to make sure you have consistent definitions (e.g., if you want to make sure MIN and MAX are defined together). E.g.:
#ifndef MY_H
#define MY_H
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define PI 3.14159
#endif
If you just have a single macro/constant you want to define, you can guard it by its own definition, like #Danh suggested.
I've been using #WilliamSwanson MAP() macro suggestion which "applies" another macro, or function, to all other macro arguments, e.g.
MAP(foo, x, y, z)
expands to
foo(x) foo(y) foo(z)
Here's the code for what I have now:
#define EVAL0(...) __VA_ARGS__
#define EVAL1(...) EVAL0 (EVAL0 (EVAL0 (__VA_ARGS__)))
#define EVAL2(...) EVAL1 (EVAL1 (EVAL1 (__VA_ARGS__)))
#define EVAL3(...) EVAL2 (EVAL2 (EVAL2 (__VA_ARGS__)))
#define EVAL4(...) EVAL3 (EVAL3 (EVAL3 (__VA_ARGS__)))
#define EVAL(...) EVAL4 (EVAL4 (EVAL4 (__VA_ARGS__)))
#define MAP_END(...)
#define MAP_OUT
#define MAP_GET_END() 0, MAP_END
#define MAP_NEXT0(test, next, ...) next MAP_OUT
#define MAP_NEXT1(test, next) MAP_NEXT0 (test, next, 0)
#define MAP_NEXT(test, next) MAP_NEXT1 (MAP_GET_END test, next)
#define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__)
#define MAP(f, ...) EVAL (MAP1 (f, __VA_ARGS__, (), 0))
... and it works well for me. However, I want to add some separator macro between every such application, i.e. get
foo(x) bar foo(y) bar foo(z)
in the example above. How would I alter the macro to do what I want? I'm guessing it must be some replacement of the end test with a one-more-till-the-end test, but I can't quite get it right. If you have your own implementation of this functionality, I suppose that would work as well (although I kind of like this one, it's relatively short and neat).
Note: This is essentially equivalent to asking how to get MAP() to do something arbitrarily different with last element as opposed to all the rest.
Here is a header file,
// a.h
#ifndef _A_H_
#define _A_H_
#ifndef MACRO_FUNC
#define MACRO_FUNC(X, Y) (X * Y + X - Y)
#endif
#endif
The above code is how I judge whether macro function MACRO_FUNC is defined or not. Is that the right way to go?
Yes this is the correct way to do it. Another way to ensure your own implementation is used is to undefine any previous definition first:
#ifdef MACRO_FUNC
# undef MACRO_FUNC
#endif
#define MACRO_FUNC(X, Y) (X * Y + X - Y)
Yes, #ifdef or #ifndef are the correct ways to test for a macro being defined. Note that you can also use #undef followed by #define to replace any existing definition.
#ifdef MACRO_FUNC
#undef MACRO_FUNC
#endif
#define MACRO_FUNC(X, Y) (X * Y + X - Y)
Also, your sample macro would be better expressed as
#define MACRO_FUNC((X), (Y)) ((X) * (Y) + (X) - (Y))
Consider what'd happen if you called MACRO_FUNC(somevar - 1, othervar + 1) if the reasons for this aren't clear.
This is the right way what you did
Yes, Since macros are evaluated by the pre-processor you need to use pre-processor directives #ifdef or #ifndef to check whether one exists.
Yes, it is how you check if the macro is already defined or not.
Notice that identifiers starting with _[A-Z] are reserved for the implementation. Change _A_H_ with A_H_ for example.
Sorry for bad English.
Suppose the code:
#define FOO(x,y) FOO ## x
#define BAR A, B
FOO(A, B) successfully expanded to FOOA. But when I write FOO(BAR), the C preprocessor (gcc -E) give error
error: macro "FOO" requires 2 arguments, but only 1 given
How I should change FOO macro if I want expand FOO(BAR) to FOOA?
#define FOO(X, Y) FOO ## X
#define BAR A, B
#define APPLY(F, X) F(X)
APPLY(FOO, BAR)
or
#define FOO(X) FOO_(X)
#define FOO_(X, Y) FOO ## X
#define BAR A, B
FOO(BAR)