Using #define in an "if" statement
Asked Answered
N

6

5

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?

Novation answered 28/12, 2011 at 22:15 Comment(1)
IMO, this isn't what constants were built for.Barquentine
F
7

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;
}
Feder answered 28/12, 2011 at 22:20 Comment(1)
All four answers are factually correct, but this is the only one that actually explains the right way to do it.Phio
M
1

#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).

Monochord answered 28/12, 2011 at 22:19 Comment(0)
C
1

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;
Cornhusk answered 28/12, 2011 at 22:23 Comment(0)
G
1

#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]).

Gomuti answered 28/12, 2011 at 22:29 Comment(0)
H
0

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.

Heavyarmed answered 28/12, 2011 at 22:19 Comment(0)
P
0

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.

Penology answered 28/12, 2011 at 22:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.