#if 0 as a define - macros

I need a way to define a FLAGS_IF macro (or equivalent) such that
FLAGS_IF(expression)
<block_of_code>
FLAGS_ENDIF
when compiling in debug (e.g. with a specific compiler switch) compiles to
if (MyFunction(expression))
{
<block_of_code>
}
whereas in release does not result in any instruction, just as it was like this
#if 0
<block_of_code>
#endif
In my ignorance on the matter of C/C++ preprocessors I can't think of any naive way (since #define FLAGS_IF(x) #if 0 does not even compile) of doing this, can you help?
I need a solution that:
Does not get messed up if */ is present inside <block_of_code>
Is sure to generate 0 instructions in release even inside inline functions at any depth (I guess this excludes if (false){<block_of_code>} right?)
Is standard compliant if possible

Macros are pretty evil, but there's nothing more evil than obfuscating control statements and blocks with macros. There is no good reason to write code like this. Just make it:
#ifdef DEBUG
if (MyFunction(expression))
{
<block_of_code>
}
#endif

The following should do what you want:
#ifdef DEBUG
# define FLAGS_IF(x) if (MyFunction((x))) {
# define FLAGS_ENDIF }
#else
# define FLAGS_IF(x) if(0) {
# define FLAGS_ENDIF }
#endif
The if(0) should turn into no instructions, or at least it does so on most compilers.
Edit: Hasturkun commented that you don't really need the FLAGS_ENDIF, so you would instead write your code like this:
FLAGS_IF(expression) {
<block_of_code>
}
with the follow macros:
#ifdef DEBUG
# define FLAGS_IF(x) if (MyFunction((x)))
#else
# define FLAGS_IF(x) if(0)
#endif

I might do something like:
#ifdef DEBUG
const bool IS_RELEASE_MODE = false;
#else
const bool IS_RELEASE_MODE = true;
#endif
if (IS_RELEASE_MODE && MyFunction(expression))
{
...
}
This should get compiled out of release builds due to the fact that if (false && f()) is the same as if (false), which gets optimized out in most compilers.
That's if you're insistent on not using #ifdef on the inside of your code. Otherwise, I'd prefer the #ifdef DEBUG if (MyFunction(expression)) { ... } #endif that someone else posted.

Why can't you use the following?
#ifdef DEBUG
code for debug mode
#else
code for release mode
#endif

I generally try to avoid too much use of conditional compilation when possible.
For one, it's usually ugly and less readable.
But even more significantly, when projects use conditional compilation to turn debugging code on & off I have sometimes run into problems that the debugging code gets stale when it's disabled. Then when I want to actually use it debugging code, I turn it on and... Things. Don't. Build. Anymore.
The debug code may reference variables or functions that no longer exist, or things around the latent debugging code have otherwise changed enough that's it's just not syntactically valid anymore.
It can be really irritating.
So I've personally taken to avoiding conditional compilation to enable/disable debugging code in favor of using an enumeration or macro (that is still conditionally compiled) to use as the condition in an if statement. When compiled as an if (0) no runtime code gets generated - exactly as desired. But, the code is still compiled and syntax checked, so it's always at least syntactically correct.
#if NDEBUG // using the same standard macro that `assert()` uses
// use your own if NDEBUG doesn't make sense
enum {
DebugOn = 0
}
#else
enum {
DebugOn = 1
}
#endif
// ... elsewhere
if (DebugOn) {
// this always gets compiled, but if it's a release build
// the compiler will not emit anything...
}
As FryGuy mentioned, you can easily combine this with calling your MyFunction() if you like - in a release build, the function will not be called due to short-circuiting, which is the behavior you specified:
if (DebugOn && MyFunction( expression)) {
// this always gets compiled, but if it's a release build
// the compiler will not emit anything...
}
But personally, I'd probably use
if (DebugOn) {
if (MyFunction( expression)) {
// ...
}
}
Which I think helps call out a little more clearly (just a little) that this is a debug-only block.
This has the advantages of always being compiled and having no flow control hidden behind macros (which several other answers have mentioned as an evil).

How about something like this:
#ifdef DEBUG
#define FLAGS_IF(expr, block) { if (MyFunction(expr)) block }
#else
#define FLAGS_IF(expr, block)
#endif
You can use it like this:
FLAGS_IF(your_favourite_expression,
({
// some code
})
)

Related

Preprocessor flag as bool input parameter?

I have a method in objective-c that takes the parameter advertisement:(BOOL)advertisement. I'm wanting to send in a preprocessor "LITE_VERSION" as the parameter and if it exists I want it to return YES, and if it doesn't NO. Is there some safe way to accomplish this without having to write anymore code?
You'd be looking at something like:
#ifdef LITE_VERSION
return YES;
#else
return NO;
#endif
This would effectively harcode one of those two return statements at compile time based on LITE_VERSION.
Or you can make it even simpler if you can guarantee you'll set LITE_VERSION to a specific value of either YES or NO:
return LITE_VERSION;

What's the use of #ifdef and #endif processor directives in iPhone?

I want to know about the use of #ifdef, #ifndef and #endif and which case, have to used those conditionals and what's the use of it? Whats the difference between the #ifdef and #ifndef?
For eg:
#define MY_Global
#ifdef MY_Global
// write some code (Inside the method)
#endif
or,
#ifdef MY_Global
-(void) customMethod
{
// Do something
}
#endif
Which one is correct, whether it should write only inside method or it does works outside method?. I haven't used this one before. so please Explain me?
Thanks!
AFAIK, #ifdef = "if defined" and #ifndef = "if not defined". These conditionals are useful, for example if you want a certain code to be compiled only for the simulator, then you'd write something like:
#if TARGET_IPHONE_SIMULATOR
#import "AccelerometerSimulation.h"
#endif
Which means, when you compile for the simulator, the AccelerometerSimulation.h will be imported. If you are compiling on a device, it is ignored totally. Hope that helps.

iphone - locating incompatible code

I have a code with two targets that uses functions specific to iOS 4 and others compatible with 3.0+.
I would like to make a final revision on the code to see if everything is fine. In other words, to see if there's no function meant for iOS4 being called when compiling for iOS 3.x target.
Is there a way to list, during compilation, any functions being called that doesn't belong to the desired version for the target?
thanks in advance.
1) turn the compiler warnings all the way up
2) treat warnings as errors
3) change the base/target SDK to the earliest version you will support
4) clean
5) build
things such as implicit functions and undeclared selectors should now generate errors.
to avoid errors going forward, create a shim static library for the functions or objc methods you will need. this shim will implement two variations of the code, and will ultimately build against the latest headers. it will contain conditional runtime checks. for the objc class methods you can fake, use categories and use the category implementation where any warning is generated.
to illustrate using two versions of the code:
/*
illustration:
- sortByCoordinates: was added in OS 4, but we need to implement or approximate it for our projects targeting OS 3 (or throw out an alert in some cases)
- as long as you have to support OS 3 and build against the SDKs from time to time, the compiler will produce errors or warnings when a selector has not been declared, or if an object may not respond to a selector (assuming you have directed the compiler to inform you of this)
- so we put our conditionals/runtime checks in a library here, and update our calls from sortByCoordinates: to mon_sortByCoordinates:
*/
- (void)mon_sortByCoordinates:(EECoordinate*)coordinates
{
/* MONLib_OSVersion_4_0 implies some constant, indicating OS 4 */
/* MONLibGetCurrentRuntimeVersion() is a call we make at runtime which returns the OS version, such as MONLib_OSVersion_4_0 or MONLib_OSVersion_3_2 */
if (MONLib_OSVersion_4_0 <= MONLibGetCurrentRuntimeVersion()) {
/* they are using OS 4 (or greater) - call the OS version */
[self sortByCoordinates:coordinates];
}
else {
/*
%%%%%% < else implement our approximation here >
*/
}
}
finally, the compiler can't catch everything for you, due to objc's dynamic nature and the way objc programs are often written. sometimes it helps to be more verbose. simple example:
#interface MONBox
/* added in version 4 */
- (NSUInteger)count;
#end
NSUInteger beispiel() {
if (0) {
/* less safe -- the compiler will not flag this */
/* if [myNSArrayInstace objectAtIndex:0] is a MONBox then this will go undetected since the selector count may be matched to -[NSArray count] */
return [[myNSArrayInstaceOfMONBoxObjects objectAtIndex:0] count];
}
else {
/* more safe -- the compiler will flag this */
MONBox * box = [myNSArrayInstaceOfMONBoxObjects objectAtIndex:0];
return [box count];
}
}
I don't think there's an automated way to do this, as far as I know. I keep an old first-gen iPhone around for this purpose -- I'll run the app on the device and see what crashes. Not ideal but it works OK for smaller apps.

Programmatically determine active configuration

Is there a way to determine the active configuration (that means Debug or Release) in code? Something along the lines of
#ifdef XCodeConfigurationDebug
...
#endif
#ifdef XCodeConfigurationRelease
...
#endif
I know that it's possible to do this by adding custom compiler flags. However, I'm looking for a more global solution.
There is the flag __OPTIMIZE__ that is defined when on RELEASE mode, and so:
#ifndef __OPTIMIZE__
// code for debug mode
#else
// code for release
#endif
i figure it out using the preprocessor declarations. you can add your own definition, or NDEBUG is another common one to declare in release.
You can also add your own preprocessor macros per configuration on your target's build settings. Ex.:
Debug
GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1
Release
GCC_PREPROCESSOR_DEFINITIONS = RELEASE=1
And then in your code
#ifdef DEBUG
...
#else
...
#endif

Detect if the iPhone is running a Debug/Distribution build at runtime

Is it possible at runtime to detect if the application that is running was compiled with debug or distribution.
In the Project Info, for a Debug configuration, add a Preprocessor Macro of "DEBUG" (in the GCC 4.2 - Preprocessing section).
In your code you can use #ifdef to see if DEBUG is defined if you want some code included or not for debug builds. Or you can even set a variable (I can't imagine why you would want this):
#ifdef DEBUG
BOOL isBuiltDebug = YES;
#else
BOOL isBuiltDebug = NO;
#endif
EDIT: Well, another way is to define a boolean value in a Preprocessor Macro, ie: "DEBUG_BUILD=1" for the Debug configuration, and "DEBUG_BUILD=0" for the Release configuration. Then you can use that value in your code:
if (DEBUG_BUILD) {
....
}
Just be careful not to use a macro name that could match a name that is already in your code or in any .h file that you might include either, because the preprocessor will replace it and it's a real pain to find those kinds of bugs.
Without having to think about defining a custom preprocessor macro, you can just write a custom method like this one :
+ (BOOL) isInDebugMode
{
#ifndef __OPTIMIZE__ // Debug Mode
return YES;
#else
return NO;
#endif
}
Or just write your code inline within those statements :
#ifndef __OPTIMIZE__ // Debug Mode
// Your debug mode code
#else
// Your release mode code
#endif
The __OPTIMIZE__ preprocessor setting in automatically set by the compiler regarding your project settings, so you don't have to worry about it.