0

I'm trying to define a macro like this:

#define SOME_DEF [[TTys getString] isEqualToString:ANOTHER_STRING]

and then doing the following:

#if SOME_DEF
...
#endif
  • [TTys getString] returns an NSString
  • ANOTHER_STRING is defined earlier as #define ANOTHER_STRING "hello"

I get the following error on the #if SOME_DEF line:

Invalid token at start of a preprocessor expression

Based on this SO question this might be caused by something that can't be resolved at compile time, but I have everything defined. My suspect is the isEqualToString method, but I don't know of another way to do this.

Community
  • 1
  • 1
  • 2
    Is there a reason you're doing this as a macro and not just a function? I can tell you from experience it's best to avoid macros when possible. – AdamPro13 Mar 30 '16 at 18:48
  • 2
    Are you expecting to evaluate the `isEqualToString:` call during the preprocessor stage? – jscs Mar 30 '16 at 18:48

1 Answers1

2

When you write #if SOME_DEF the preprocessor resolves it into:

#if [[TTys getString] isEqualToString:ANOTHER_STRING]

This is not a valid condition for the #if preprocessor directive:

The ‘#if’ directive allows you to test the value of an arithmetic expression, rather than the mere existence of one macro. Its syntax is

 #if expression

 controlled text

 #endif /* expression */ 

expression is a C expression of integer type, subject to stringent restrictions. It may contain

  • Integer constants.
  • Character constants, which are interpreted as they would be in normal code.
  • Arithmetic operators for addition, subtraction, multiplication, division, bitwise operations, shifts, comparisons, and logical operations (&& and ||). The latter two obey the usual short-circuiting rules of standard C.
  • Macros. All macros in the expression are expanded before actual computation of the expression's value begins.
  • Uses of the defined operator, which lets you check whether macros are defined in the middle of an ‘#if’.

  • Identifiers that are not macros, which are all considered to be the number zero. This allows you to write #if MACRO instead of #ifdef MACRO, if you know that MACRO, when defined, will always have a nonzero value. Function-like macros used without their function call parentheses are also treated as zero.

From the GCC documentation.

What you can do instead is using a runtime-evaluated regular if-statement:

if(SOME_DEF) {
    ...
}
Tamás Zahola
  • 9,271
  • 4
  • 34
  • 46