#define vs const in Objective-C

c-preprocessor, constants, objective-c

Solution

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.

`const`s are much more compiler and debugger friendly than `#define`s. 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 `#define`s and `const`s 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

`const`s 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 `enum`s for constants of other types, I use `const` unless I have a very good reason not to.

Problem

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?

Original source