Jonah
Jonah

Reputation: 4800

Using #define in an "if" statement

Is it possible to use #define in an "if" statement? The following code works, but I get a warning that the macro is being redefined.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
 #define TableViewHeight 916
 #define DisplayHeight 1024
 #define DisplayWidth 768
}
else {
 #define TableViewHeight 374
 #define DisplayHeight 480
 #define DisplayWidth 320
}

I also tried this, but it didn't work:

#ifdef UIUserInterfaceIdiomPad
 #define TableViewHeight 916
 #define DisplayHeight 1024
 #define DisplayWidth 768
#else
 #define TableViewHeight 374
 #define DisplayHeight 480
 #define DisplayWidth 320
#endif

Any ideas?

Upvotes: 5

Views: 12589

Answers (6)

Andrew Madsen
Andrew Madsen

Reputation: 21383

#defines are substituted by the preprocessor before the compiler runs. This means that you can't set their value at run time. The way I might do what you're going for is something like this:

In your .h file:

static CGFloat TableViewHeight;
static CGFloat DisplayHeight;
static CGFloat DisplayWidth;

in the .m file (class implementation):

+ (void)initialize
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
     TableViewHeight = 916.0;
     DisplayHeight = 1024.0;
     DisplayWidth = 768.0;
    } else {
     TableViewHeight = 374.0;
     DisplayHeight = 480.0;
     DisplayWidth = 320.0;
    }
}

Alternatively, you could do something like this:

#define TableViewHeight ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 916.0 : 374.0)
#define DisplayHeight ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 1024.0 : 480.0)
#define DisplayWidth ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 768.0 : 320.0)

Finally, for DisplayHeight and DisplayWidth, you don't really need to do any of this and are probably better off using CGRectGetHeight([[UIScreen mainScreen] bounds]) and CGRectGetWidth([[UIScreen mainScreen] bounds]).

Upvotes: 1

Jeremy
Jeremy

Reputation: 9030

I think you answered your own question :) To remove the warnings, though, why not declare those as variables instead of macros?

I would do this:

CGFloat tableHeight = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 916.0f : 374.0f;

Upvotes: 1

Luke
Luke

Reputation: 7220

No, unfortunately. #define is used by the preprocessor to replace symbols before the code is compiled, while if is part of the actual code to be compiled. In the first case, the preprocessor knows nothing about what the result of your if statement will be.

The second case doesn't make sense because you don't care about whether UIUserInterfaceIdiomPad is defined, you care whether UI_USER_INTERFACE_IDIOM() has that value.

Upvotes: 0

CB Bailey
CB Bailey

Reputation: 793057

Yes, it's possible but it probably doesn't do what you think. Preprocessor directives are interpreted before the results of the preprocessing step are compiled.

This means that all of the preprocessor directives are interpreted, redefining some of the macros, before the remaining code, which will look something like below, is compiled.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
}
else {
}

In other words, after preprocessing, you just have empty if and else bodies.

If you want to change the value of something based on a condition at run time then that something will have to be an genuine object and not just a preprocessor macro. E.g.

extern int TableViewHeight; // defined somewhere else
extern int DisplayHeight; // defined somewhere else
extern int DisplayWidth; // defined somewhere else

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  TableViewHeight = 916;
  DisplayHeight = 1024;
  DisplayWidth = 768;
}
else {
  TableViewHeight = 374;
  DisplayHeight = 480;
  DisplayWidth = 320;
}

Upvotes: 7

Tom van der Woerdt
Tom van der Woerdt

Reputation: 29985

Use #if instead of a normal if.

However that would be a preprocessor thing which would mean your application would simply only compile for either the iPhone or the iPad (if it even worked).

Bottom line: no, you cannot use macros. They are checked while compiling and not while running the application.

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272727

#define (and #ifdef, etc.) are processed by the preprocessor. This runs entirely before the compiler itself; they are really two completely separate processes. So it doesn't interact at all with constructs like if.

Your second code example might work, if UIUserInterfaceIdiomPad is a macro (i.e. it has been #defined).

Upvotes: 1

Related Questions