Objective-C macro in preprocessor IF - objective-c

I have a project with some macros that are defined using Objective-C statements, like this:
#define TEST [someObject someNumber] == 500
I need to define another value based on this result, like this:
#if TEST
#define THING = 1
#else
#define THING = 2
#endif
But, this doesn't work. And I can't use #ifdef TEST because the value is always defined. Even if it's false, it's still defined.
TEST is based on an ObjC statement, and it seems like the preprocessor has no way of evaluating it. So, is there no way to test for this?

In the comments you wrote:
Since TEST must be evaluated during runtime, there's no way to know the value of it during build time. Because the preprocessor can't know the value, it can't test it. Is this correct?
Yes.
The preprocessor runs (at least logically) before the rest of the compiler. It is essentially language and syntax agnostic, and does not even have access to constants defined in your code. The conditional constructs operate solely with preprocessor tokens.

Related

Visual Objects - Retrieving string DEFINE dynamically - #ifdef is returning false

This is regarding the Visual Objects programming language based upon Clipper.
I'm trying to load the values of a few DEFINE constants, I've tried using #ifdef to determine if they exist however it doesn't seem to work with strings, just numbers or logics, e.g.:
DEFINE TEST_LOGIC := True
DEFINE TEST_NUM := 1
DEFINE TEST_STRING := "HELLO"
#IFDEF TEST_LOGIC
// Runs
#ENDIF
#IFDEF TEST_NUM
// Runs
#ENDIF
#IFDEF TEST_STRING
// Does not run
#ENDIF
Is there some other way of determining whether they exist and returning their values? I've tried VarGet() and MemVarGet() but they can't see the constant and cause a runtime error, and #ifdef cannot accept a method call like !Empty(TEST_STRING) (will not compile), using a direct comparison like #ifdef TEST_STRING > " " also doesn't work (compiles and runs but the code block does not execute).
There doesn't seem to be a way to do this using DEFINE statements containing strings, however if it's changed to a GLOBAL declaration then the #ifdef statement will work as expected.

Two different CMake difinitions

With CMake when some definitions are defined they are defined in this way:
add_definitions(-DMY_DEFINITION)
Sometimes I see people make the definitions in a different way:
add_definitions(-DMY_DEFINITION=1)
Then my question is what's the difference between them in the generated C++ project. Thanks.
This is not really related to CMake but more to the C/++ compiler.
In the code the difference is the same between :
#define MY_DEFINITION
and
#define MY_DEFINITION 1
Actually there's not need to define a value for a C/++ macro if the only thing you want is to know if the macro exists (has been defined), like a "flag". Best example is the header include guards :
#ifndef MYHEADER
#define MYHEADER
// ...
#endif
But sometimes people prefer setting a value (like =1) even if they don't need it, because it's more exhaustive, or clear.
More generally speaking when you affect a value to a macro it is because you expect the macro name to be expanded to the value. When not you just expect the value to exist. The way tests are done may be different :
With -DMY_DEFINITION:
#ifdef MY_DEFINITION
// Do something
#else
// Do somthing else
#endif
With -DMY_DEFINITION=1
#if MY_DEFINITION
// Do something
#else
// Do somthing else
#endif

Objective-c disable function with conditional macros

I have a custom logging function that i would like to disable for realease builds. But the problem is it only lets me to replace that function with another empty one. Here's what i would like to do:
#ifdef SMTH
#define logfunction(...)
#else
void logfunction(NSString *fmt, ...) { some logging code goes here }
#endif
To make this work, i could replace the function with a macro, including VA_ARGS and such, but ... the problem is that my xCode loses code completion inside the braces of logfunction(). Now if the logging facility is defined as a function - code completion works fine.
The only solution i have so far is this:
#ifdef SMTH
void logfunction(NSString *fmt, ...) { /* no code here */ }
#else
void logfunction(NSString *fmt, ...) { some logging code goes here }
#endif
This works fine, but there is a call to an empty function in release builds. Is there any way to work around this?
UPDATE - my bad - everything works
The first example actually works, i simply forgot to do the same conditional macro in the ".h" file ...
I think that your current solution is already good enough. The empty function wont cause much trouble (in terms of wasting much time when it is called). Probably the compiler will even remove the call to the empty function altogether.
However, if you still want to get rid of it, you can try what I am doing:
Wrap your log function into a macro, and define that macro conditionally.
Example:
#ifdef SMTH
#define logfunction(fmt, ...)
#else
#define logfunction(fmt, ...) __logfunction((fmt), ##__VA_ARGS__)
#endif
where __logfunction(NSString *fmt, ...) is your actual logging function. This will completely remove the call to the function, when your SMTH is set.
By the way, you may want to use the DEBUG flag, that is set per default in XCode for non-release builds (see the "Preprocessor Macros" setting in your target in XCode). You would need to switch the cases around inside the #ifdef, obviously, or make it a #ifndef DEBUG.

#define vs const in Objective-C

I'm new to Objective-C, and I have a few questions regarding const and the preprocessing directive #define.
First, I found that it's not possible to define the type of the constant using #define. Why is that?
Second, are there any advantages to use one of them over the another one?
Finally, which way is more efficient and/or more secure?
First, I found that its not possible to define the type of the constant using #define, why is that?
Why is what? It's not true:
#define MY_INT_CONSTANT ((int) 12345)
Second, are there any advantages to use one of them over the another one?
Yes. #define defines a macro which is replaced even before compilation starts. const merely modifies a variable so that the compiler will flag an error if you try to change it. There are contexts in which you can use a #define but you can't use a const (although I'm struggling to find one using the latest clang). In theory, a const takes up space in the executable and requires a reference to memory, but in practice this is insignificant and may be optimised away by the compiler.
consts are much more compiler and debugger friendly than #defines. In most cases, this is the overriding point you should consider when making a decision on which one to use.
Just thought of a context in which you can use #define but not const. If you have a constant that you want to use in lots of .c files, with a #define you just stick it in a header. With a const you have to have a definition in a C file and
// in a C file
const int MY_INT_CONST = 12345;
// in a header
extern const int MY_INT_CONST;
in a header. MY_INT_CONST can't be used as the size of a static or global scope array in any C file except the one it is defined in.
However, for integer constants you can use an enum. In fact that is what Apple does almost invariably. This has all the advantages of both #defines and consts but only works for integer constants.
// In a header
enum
{
MY_INT_CONST = 12345,
};
Finally, which way is more efficient and/or more secure?
#define is more efficient in theory although, as I said, modern compilers probably ensure there is little difference. #define is more secure in that it is always a compiler error to try to assign to it
#define FOO 5
// ....
FOO = 6; // Always a syntax error
consts can be tricked into being assigned to although the compiler might issue warnings:
const int FOO = 5;
// ...
(int) FOO = 6; // Can make this compile
Depending on the platform, the assignment might still fail at run time if the constant is placed in a read only segment and it's officially undefined behaviour according to the C standard.
Personally, for integer constants, I always use enums for constants of other types, I use const unless I have a very good reason not to.
From a C coder:
A const is simply a variable whose content cannot be changed.
#define name value, however, is a preprocessor command that replaces all instances of the name with value.
For instance, if you #define defTest 5, all instances of defTest in your code will be replaced with 5 when you compile.
It is important to understand the difference between the #define and the const instructions which are not meant to the same things.
const
const is used to generate an object from the asked type that will be, once initialised, constant. It means that it is an object in the program memory and can be used as readonly.
The object is generated every time the program is launched.
#define
#define is used in order to ease the code readability and future modifications. When using a define, you only mask a value behind a name. Hence when working with a rectangle you can define width and height with corresponding values. Then in the code, it will be easier to read since instead of numbers there will be names.
If later you decide to change the value for the width you would only have to change it in the define instead of a boring and dangerous find/replace in your whole file.
When compiling, the preprocessor will replace all the defined name by the values in the code. Hence, there is no time lost using them.
In addition to other peoples comments, errors using #define are notoriously difficult to debug as the pre-processor gets hold of them before the compiler.
Since pre-processor directives are frowned upon, I suggest using a const. You can't specify a type with a pre-processor because a pre-processor directive is resolved before compilation. Well, you can, but something like:
#define DEFINE_INT(name,value) const int name = value;
and use it as
DEFINE_INT(x,42)
which would be seen by the compiler as
const int x = 42;
First, I found that its not possible to define the type of the constant using #define, why is that?
You can, see my first snippet.
Second, are there any advantages to use one of them over the another one?
Generally having a const instead of a pre-processor directive helps with debugging, not as much in this case (but still does).
Finally, which way is more efficient and/or more secure?
Both are as efficient. I'd say the macro can potentially be more secure as it can't be changed during run-time, whereas a variable could.
I have used #define before to help create more methods out of one method like if I have something like.
// This method takes up to 4 numbers, we don't care what the method does with these numbers.
void doSomeCalculationWithMultipleNumbers:(NSNumber *)num1 Number2:(NSNumber *)num2 Number3:(NSNumber *)num23 Number3:(NSNumber *)num3;
But I also what to have a method that only takes 3 numbers and 2 numbers so instead of writing two new methods I am going to use the same one using the #define, like so.
#define doCalculationWithFourNumbers(num1, num2, num3, num4) \
doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), (num4))
#define doCalculationWithThreeNumbers(num1, num2, num3) \
doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), nil)
#define doCalculationWithTwoNumbers(num1, num2) \
doSomeCalculationWithMultipleNumbers((num1), (num2), nil, nil)
I think this is a pretty cool thing to have, I know you can go straight to the method and just put nil in the spaces you don't want but if you are building a library it is very useful. Also this is how
NSLocalizedString(<#key#>, <#comment#>)
NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>)
are done.
Whereas I don't believe you can do this with constants. But constants do have there benefits over #define like you can't specify a type with a #define because it is a pre-processor directive that is resolved before compilation, and if you get an error with #define they are harder to debug then constants. Both have there benefits and downsides but I would say it all depends on the programmer to which one you decided to use. I have written a library with both them in using the #define to do what I have shown and constants for declaring constant variables which I need to specify a type on.

enum or define, which one should I use?

enum and #define appears to be able to do the same thing, for the example below defining a style. Understand that #define is macro substitution for compiler preprocessor. Is there any circumstances one is preferred over the other?
typedef enum {
SelectionStyleNone,
SelectionStyleBlue,
SelectionStyleRed
} SelectionStyle;
vs
#define SELECTION_STYLE_NONE 0
#define SELECTION_STYLE_BLUE 1
#define SELECTION_STYLE_RED 2
Don't ever use defines unless you MUST have functionality of the preprocessor. For something as simple as an integral enumeration, use an enum.
An enum is the best if you want type safety. They are also exported as symbols, so some debuggers can display them inline while they can't for defines.
The main problem with enums of course is that they can only contain integers. For strings, floats etc... you might be better of with a const or a define.
The short answer is that it probably doesn't matter a lot. This article provides a pretty good long answer:
http://www.embedded.com/columns/programmingpointers/9900402?_requestid=345959
When there's a built-in language feature supporting what you want to do (in this case, enumerating items), you should probably use that feature.
Defines are probably slightly faster (at runtime) than enums, but the benefit is probably only a handful of cycles, so it's negligible unless you're doing something that really requires that. I'd go with enum, since using the preprocessor is harder to debug.
#define DEFINED_VALUE 1
#define DEFINED_VALUE 2 // Warning
enum { ENUM_VALUE = 1 };
enum { ENUM_VALUE = 2 }; // Error
With #define, there is a higher probability of introducing subtle bugs.