Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

#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?

like image 678
ObjectiveCoder Avatar asked Jun 22 '12 09:06

ObjectiveCoder


3 Answers

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.

like image 188
JeremyP Avatar answered Nov 09 '22 12:11

JeremyP


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.

like image 18
MegaNairda Avatar answered Nov 09 '22 13:11

MegaNairda


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.

like image 12
fBourgeois Avatar answered Nov 09 '22 12:11

fBourgeois