I want to define a macro kDependentMacro to be 38 if the macro kIndependentMacro is defined and 40 otherwise. What is the simplest way to do that?
#ifdef kIndependentMacro
# define kDependentMacro 38
#else
# define kDependentMacro 40
#endif
Related
I have to maintain C code that has both generic components and product specific components. I would like to simplify my code so that I have just one generic product.h file which has a structure like
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#else
#if (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
#endif
Then, whenever I have a header foo.h which has product specific components, I would like to use syntax like this
#include "product.h"
#include PRODUCT_SPECIFIC_INCLUDE
where PRODUCT_SPECIFIC_INCLUDE should be derived from __FILE__ and PRODUCT_NAME macro in such a way that it would translate to
#include "Product1/foo.h"
that is, the product specific header file has the same filename as the generic file, but is located in a product specific folder, whose name is the value of PRODUCT_NAME macro.
It seems that whatever I try has preprocessor stringification issues. I can't be the first to want such a structure. What am I missing?
Update
Here is what I currently have for PRODUCT_SPECIFIC_INCLUDE which does not work
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
You can do something like
#define STR2(F) #F
#define STR(F) STR2(F)
#define MAKE_PRODUCT_INCLUDE(FILE) STR(PRODUCT_SPECIFIC/FILE)
#include MAKE_PRODUCT_INCLUDE(foo.h)
but I don't know a way to avoid repeating the file name. Using __FILE__ gives a string and there is no way that I know to concatenate strings in the preprocessor (the fact that juxtaposed strings are concatenated is a parser feature, and ## is not usable for that "foo""bar" is not the spelling of a valid token).
The first code could be reduced to:
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#elif (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
Secondly, you are trying to get the required include header name but the problem is in these two lines:
#define TOKENPASTE(x, y) x ## y
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
__FILE__ : This macro expands to the name of the current input file,
in the form of a C string constant
TOKENPASTE(PRODUCT_SPECIFIC, __FILE__) |--> product ## "foo.h"
product and " can never give a valid token. And that's why the CPP gives you error. What you need is writing the filename as plaintext so you can combine it with other macros.
You can do it like this:
#define TOKENPASTE(x) #x
#define TOKENPASTE2(x) TOKENPASTE(x)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC/foo.h)
#include PRODUCT_SPECIFIC_INCLUDE
Suppose I have some macro #define NAME name, and I want to define some other macro which will expand to the quoted value. That is, as if I had also defined #define NAME_STR "name". Is there a neater way than the following?
#define QUOT(str) #str
#define QUOT_ARG(str) QUOT(str)
#define NAME_STR QUOT_ARG(NAME)
Not really, due to the fact that macro arguments are not expanded when used in stringification. From the GNU C PreProcessor manual:
Unlike normal parameter replacement,
the argument is not macro-expanded
first. This is called stringification.
From the same source:
If you want to stringify the result of
expansion of a macro argument, you
have to use two levels of macros.
...which continues with an example:
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)
==> "foo"
xstr (foo)
==> xstr (4)
==> str (4)
==> "4"
I am developing an application where i need to define several constants that will be used in more than one class.I have defined all my constants in one .h file(say "constants.h") and imported that file in myAppName_Prefix.pch file located in "Other sources" folder of the project.The classes using these constants are being compiled with out any error but other classes, where i declared some UISwipeGestureRecognizers, are throwing error as"Expected identifier before numeric constant"
this is the snippet of code from one of the classes that is showing error:
if (gesture.direction==UISwipeGestureRecognizerDirectionLeft)
i defined my constants as:
#define heading 1
#define direction 2
#define statement 3
#define refLink 4
#define correctResponse 5
#define incorrect1Response 6
if i define them in each class individually then everything as working fine.
Can any one please suggest me a way how to solve this issue.
After preprocessing your code
if (gesture.direction==UISwipeGestureRecognizerDirectionLeft)
looks like this
if (gesture. 2==UISwipeGestureRecognizerDirectionLeft)
and this is obviously not valid code.
The solution is to put an unique namespace string in front of your #defines.
#define hariDirection 2
or
#define kDirection 2
Or imho the best solution: don't use #define
typedef enum {
heading = 1,
direction,
statement,
refLink,
correctResponse,
incorrect1Response,
} MyDirection;
This will do the same thing, but it won't clash with other method and variable names.
I was getting the same error message from gcc.
error: expected ')' before numeric constant
#define UNIQUE_NAME 0
After checking that my variable names were unique, I realised that I had a typo at the point in the code where the constant was being used.
#define UNIQUE_NAME 0
//...
if (test_variable UNIQUE_NAME) { //missing ==
//...
}
simple mistake, but tricky to find because gcc was pointing me towards the #define statement
Make your constants names to be unique:
#define kHeading 1
#define kDirection 2
#define kStatement 3
#define kRefLink 4
#define kCorrectResponse 5
#define kIncorrect1Response 6
#define A #"someString"
#define B NSLocalizedString(#"someLocalizableString",nil) A
I'm trying to concatenate a localizable string in a "#define" but it's not work. It's that possible to do that in a Macro please?
#define A #"someString"
#define B [NSLocalizedString(#"someLocalizableString",nil) stringByAppendingString:A]
the result is somelocalizableStringsomeString
There are different kind of macros in the C language, nested macro is one of them.
Considering a program with the following macro
#define HYPE(x,y) (SQUR(x)+SQUR(y))
#define SQUR(x) (x*x)
Using this we can successfully compile to get the result.
As we all know the C preprocessor replaces all the occurrence of the identifiers with the replacement-string. Considering the above example I would like to know how many times the C preprocessor traverses the program to replace the macro with the replacement values. I assume it cannot be done in one go.
the replacement takes place, when "HYPE" is actually used. it is not expanded when the #define statement occurs.
eg:
1 #define FOO 1
2
3 void foo() {
4 printf("%d\n", FOO);
5 }
so the replacement takes place in line 5, and not in line 1. hence the answer to your question is: once.
A #define'd macro invocation is expanded until there are no more terms to expand, except it doesn't recurse. For example:
#define TIMES *
#define factorial(n) ((n) == 0 ? 1 : (n) TIMES factorial((n)-1))
// Doesn't actually work, don't use.
Suppose you say factorial(2). It will expand to ((2) == 0 ? 1 : (2) * factorial((2)-1)). Note that factorial is expanded, then TIMES is also expanded, but factorial isn't expanded again afterwards, as that would be recursion.
However, note that nesting (arguably a different type of "recursion") is in fact expanded multiple times in the same expression:
#define ADD(a,b) ((a)+(b))
....
ADD(ADD(1,2),ADD(3,4)) // expands to ((((1)+(2)))+(((3)+(4))))