Reputation: 129
I have been reading conflicting information about the use of #define macros in iOS and whether they are running only on compile time or also at run time.
Consider my case: i would like to define a macro that returns a BOOL pertaining to whether the screen is of large size or small size, here is the code:
#define TTThisScreenWidth [[UIScreen mainScreen] bounds].size.width
#define TTLargeScreenTrushHold 700.0f
#define TTScreenIsOfLargeSize (TTThisScreenWidth > TTLargeScreenTrushHold)
Problem: If this code only runs on compile time than the screen size will be fixed on the device it was compiled to, and NOT return the correct answer when running on a device with a different screen..
HOWEVER: i checked it out, and it works perfectly on the iPad, when initially compiled for the iPhone (universal app)
SO: is it safe to not?
thanks!
Upvotes: 2
Views: 873
Reputation: 7085
It should be noted here, that the while there is more to the C preprocessing engine in the #if, #ifdef, #endif, etc... cases, in the cases specified the question, the preprocessor engine works as a TEXT replacement engine.
This is why when lets say one does something like:
#define varA 10
#define varB 20
#define addAB varA + varB
if there is a call to addAB in the real compiled code it will be replaced with "varA + varB". It is and always will be good practice to perform mathematical operations then as follows:
#define addAB (varA + varB)
Why is this: if I were to simply use the first definition of addAB, then if I did something like:
myVar = 5 * addAB;
then the text replacement engine would make it look like:
myVar = 5 * varA + varB;
prior to compile. If the original intent was to first add a and b prior to multiplication then this will not be your result. If instead the second is used then:
myVar = 5 * (varA + varB);
becomes the resultant expression prior to compile and this WILL get you what you want. Remembering that the preprocessor in these cases is a SIMPLE TEXT replacement engine will get you far.
Upvotes: 1
Reputation: 21221
#define
is a precompiled direvative used to define constants and macros
How it works:
Consider this example
#define MYINT 5
#define MYSTRING @"number is %d"
in your .m file
NSString *str = [NSString stringWithFormat:MYSTRING, MYINT];
//What really happens is
NSString *str = [NSString stringWithFormat:@"number is %d", 5];
Each define is replaced by the value or code it defines
Upvotes: 1
Reputation: 727077
Macros are replaced at compile time; they do not run at compile time. The body of the macro will be "pasted in" in place of the reference to the name of the macro, as if you typed it in manually.
In general, compiler will evaluate constant expressions at compile time, with or without macros. Your TTThisScreenWidth
does not involve constant expressions - it is a run-time expression, so it is evaluated at run time.
Upvotes: 5
Reputation: 43470
A macro instructs the C preprocessor to substitute its value for its name. It does not run methods or functions, nor anything else complex. In your code, if you use your macro TTScreenIsOfLargeSize
like so:
if (TTScreenIsOfLargeSize) {
/* ... */
}
This actually evaluates to:
if ([[UIScreen mainScreen] bounds].size.width > 700.0f) {
/* ... */
}
Because [UIScreen mainScreen]
etc. is not evaluated at compile-time.
Upvotes: 4