if else define for preprocessor - objective-c

//initial code:
#define MYDEBUG YES
#if (defined(MYDEBUG) && MYDEBUG == YES)
#define NATIVEUNITID #"unitid_debug"
#else
#define NATIVEUNITID #"unitid_release"
#endif
//somewhere inside the code
NATIVEUNITID is #"unitid_release"
May be I do not understand something. But why? What is the proper way to define
NATIVEUNITID using the other define?
I've tried both #if (MYDEBUG) and #if (MYDEBUG == true) but I obtain the same result.
Please, help me to understand this simple case. How can I receive
NATIVEUNITID is #"unitid_debug" ?

The preprocessor cannot evaluate == for "strings".
You could retain your notation if you write #DEFINE YES 1

To improve this answer
#if !defined(YES)
#define YES (BOOL)1
#endif
#if !defined(NO)
#define NO (BOOL)0
#endif
before
#define MYDEBUG YES

Related

extern function with macro

Im having a linker problem in Objective C when i attempt to do a marco with a extern function. Any idea why?
Header file
To assist in doing comparison with the device version
extern NSString* getOperatingSystemVerisonCode();
#if TARGET_OS_IPHONE // iOS
#define DEVICE_SYSTEM_VERSION [[UIDevice currentDevice] systemVersion]
#else // Mac
#define DEVICE_SYSTEM_VERSION getOperatingSystemVerisonCode()
#endif
#define COMPARE_DEVICE_SYSTEM_VERSION(v) [DEVICE_SYSTEM_VERSION compare:v options:NSNumericSearch]
#define SYSTEM_VERSION_EQUAL_TO(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) (COMPARE_DEVICE_SYSTEM_VERSION(v) != NSOrderedDescending)
.mm file
NSString* getOperatingSystemVerisonCode()
{
/*
[[NSProcessInfo processInfo] operatingSystemVersionString]
*/
NSDictionary *systemVersionDictionary =
[NSDictionary dictionaryWithContentsOfFile:
#"/System/Library/CoreServices/SystemVersion.plist"];
NSString *systemVersion =
[systemVersionDictionary objectForKey:#"ProductVersion"];
return systemVersion;
}
Linker Error:
Undefined symbols for architecture x86_64:
"_getOperatingSystemVerisonCode", referenced from:
-[Manager isFeatureAvailable] in Manager.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The problem is not caused by the macro definition.
The getOperatingSystemVerisonCode() function is defined in a ".mm" file and therefore
compiled as Objective-C++. In particular, the function name is mangled as a C++ function.
But when referenced from (Objective-)C sources, the unmangled name is expected.
You have two options to solve the problem:
Rename the ".mm" file to ".m", so that it is compiled as an Objective-C file.
In the header file where the function is declared, add the extern "C" declaration to enforce C linkage even in an (Objective-)C++ file:
#ifdef __cplusplus
extern "C" {
#endif
NSString* getOperatingSystemVerisonCode();
#ifdef __cplusplus
}
#endif
For more information about mixing C and C++, see for example
Combining C++ and C - how does #ifdef __cplusplus work?

Input value into define method

Get confusing define methods below
#define SELF_PASSWORD #"0"
#define SELF_DROPBOX #"1"
#define SELF_ABOUT #"2"
#define SELF_TABLE_TITLE_PASSWORD #"Password"
#define SELF_TABLE_TITLE_DROPBOX #"Dropbox"
#define SELF_TABLE_TITLE_ABOUT #"About"
#define SELF_TABLE_HEADER_TITLE(SECTION) = SECTION==SELF_PASSWORD? SELF_TABLE_TITLE_PASSWORD:SECTION==SELF_DROPBOX?SELF_TABLE_TITLE_DROPBOX:SELF_TABLE_TITLE_ABOUT
-(void)buttonActionPassword:(UIButton *){
NSLog(#“Title : %#”, SELF_TABLE_HEADER_TITLE(SELF_PASSWORD));
}
-(void)buttonActionAbout:(UIButton *){
NSLog(#“Title : %#”, SELF_TABLE_HEADER_TITLE(SELF_ABOUT));
}
can we use SELF_TABLE_HEADER_TITLE(SELF_PASSWORD) method?
Xcode error says ‘Expected expression’ what is that issue?
Issue fixed,
#define SELF_TABLE_HEADER_TITLE(key) [key isEqual:SELF_PASSWORD]?SELF_TABLE_TITLE_PASSWORD:[key isEqual:SELF_DROPBOX]?SELF_TABLE_TITLE_DROPBOX:SELF_TABLE_TITLE_ABOUT;
"==" is not work. working use isEqual function.

In Objective c how to define custom boolean type?

typedef signed char BOOL;
// BOOL is explicitly signed so #encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif
Above is how BOOL is defined in iOS. Following the same way i am trying to define another boolean with value ON OFF and did like below.
typedef signed char ONOFF;
#if __has_feature(objc_bool)
#define ON __objc_yes
#define OFF __objc_no
#else
#define ON ((ONOFF)1)
#define OFF ((ONOFF)0)
#endif
When this type defined as parameter autocompletion write it as 'int' instead of 'ONOFF'. But for BOOL type it rightly writing it as 'BOOL'.
Is that possible to create my custom boolean type that works similarly like BOOL in all aspects?
For some properties the readability will be better with ON/OFF, hence trying the above.
Any suggestions?
Edit
One quick work around to use ON/OFF in place of YES/NO is
typedef YES ON;
typedef NO OFF;
But still wondering why i cannot create my own boolean type.
Keep it simple?
typedef BOOL ONOFF;
#define ON YES
#define OFF NO

Preprocessor macro and BOOL weirdness

Code below yields the output "yes defined", "no defined" and "yes". Why?
#define FOOBAR NO
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef YES
NSLog(#"yes defined");
#endif
#ifdef NO
NSLog(#"no defined");
#endif
#if FOOBAR == YES
NSLog(#"yes");
#else
NSLog(#"no");
#endif
// ...
}
YES and NO are not undefined, objc.h defines them as:
typedef signed char BOOL;
#define YES (BOOL)1
#define NO (BOOL)0
What is the value of NO? If it's undefined (like YES), they will both evaluate to 0.
This means your expression is essentially
#if 0 == 0
which is of course true, and thus causes the first call to be compiled.
UPDATE: Not sure how BOOL is defined, but casting to what might be a typedef:ed type is not a very good idea when dealing with the preprocessor. Remember that the the #if is evaluated by the preprocessor, not by the compiler. Read something like this for more information about expressions in the preprocessor. Especially:
The preprocessor does not know anything about types in the language.
All identifieres that the preprocessor doesn't know of are replaced with 0 for evaluation in #if directives. If you don't have defined YES and NO both are 0 (and thus equal).

Preprocessor-IF doesn't work

I'm trying to check with Preprocessor-Ifs if the Device is an iPad. If it is an iPad, I want to define something Devicespecific, but for some reason I can't check in an PP-IF if a PP-Constant is true.
Maybe you got an idea?
#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif
#if IS_IPAD
#define WIDTH 768
#define HEIGHT 1024
#else
#define WIDTH 320
#define HEIGHT 480
#endif
Preprocessor rules are, (surprise, surprise) processed prior to building the app. Since it's an universal app, it doesn't yet know if it's running on an iPad or an iPhone.
Use this:
#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif
#define WIDTH (IS_IPAD ? 768 : 320)
#define HEIGHT (IS_IPAD ? 1024 : 480)
This is my approach: you can use this in the header file
#define _IPAD ((__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200) && (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad))
#define GUI_TITLE_LABEL_WIDTH (_IPAD? 220*2 : 220)
#define UI_FONT_SIZE (_IPAD? 20 : 16)
Short and easy :D
You have a runtime check inside of a #if statement. A preprocessor check will not evaluate (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) so the width and height will have to be set at runtime since you can not tell if it is an iPad until runtime. I would also recommend using 0 instead of false.
(When you ask a question on SO, you should tell what you tried, and what happened.)
Anyway, I think you will not be able to do what you want there, because at compile time, the compiler does not know what device you will be running on. You could compile the code, and then run on an iPad, and iPhone, an iPod - how could the pre-processor possibly know which device you will be running on in the future?