Imagine a situation where you want to statically initialize an array with values different to 0:

1

2

3

4

#define ARRAY_SIZE 8

intMY_ARRAY[ARRAY_SIZE]={

42,42,42,42,42,42,42,42

};

This approach works, at least until someday you want to increase the array size to, say, 200. In this case, you have to add 192 times “42, ” to the initializer list. What a dread!

Everything would be easy, if you wanted to zero-initialize the array:

1

2

#define ARRAY_SIZE 200

intMY_ARRAY[ARRAY_SIZE]={0};

With zero-initialization, all you have to do is specify the value of the first element – all of the remaining elements will automatically be set to zero.

But sometimes you need a value different to 0 and you don’t want an additional call to “memset()” at run-time. Or you cannot use “memset()” because your array is stored in a read-only ROM segment and you cannot change the array’s values dynamically.

Basically, what you want is this:

1

2

3

4

#define ARRAY_SIZE 200

intMY_ARRAY[ARRAY_SIZE]={

STATIC_INIT(42,ARRAY_SIZE)

};

Then, you would only have to make a single change to alter the size of the array (or the initialization value).

Alas, it turns out that it is impossible to define a macro that does the job we expect from “STATIC_INIT”. Think about it for a while. How would you solve this problem?

Sometimes, it is possible to replace a call to an impossible macro with the inclusion of a header file; I call this technique the “Replace macro call with file inclusion” trick:

1

2

3

4

5

6

#define ARRAY_SIZE 200

intMY_ARRAY[ARRAY_SIZE]={

#define STATIC_INIT_VALUE 42

#define STATIC_INIT_COUNT ARRAY_SIZE

#include "static_init.h"

};

The two defines represent the macro parameters and the inclusion of the header file represents the actual macro call.

You probably wonder what the contents of “static_init.h” are, but it’s instructive to spend some time on this problem yourself. Afterwards, you can have a look at my solution.

Note that this approach is not limited to single values – you can also use it for more complex initializations. For instance, if you need an alternating sequence of ’42’ and ’13’ you would do this:

1

2

3

4

5

6

#define ARRAY_SIZE 200

intMY_ARRAY[ARRAY_SIZE]={

#define STATIC_INIT_VALUE 42, 13

#define STATIC_INIT_COUNT (ARRAY_SIZE / 2)

#include "static_init.h"

};

I’ve also used the “Replace macro call with file inclusion” trick to encapsulate #pragmas and other compiler-specific features. Consider the case where you are working on a multi-platform project that uses different compilers. Consider further that you have a piece of code that generates compiler warnings and you want to locally turn compiler warnings off:

1

2

3

4

5

#pragma warning off

...

// nasty code

...

#pragma warning on

Now the problem with this approach is that #pragmas are compiler-dependent, which means that you will end up with something like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

#if COMPILER1

#pragma warning off

#elif COMPILER2

#pragma nowarn -save

#elif COMPILER3

#nowarn

#else

#error Compiler not supported.

#endif

...

// Nasty code

...

#if COMPILER1

#pragma warning on

#elif COMPILER2

#pragma nowarn -restore

#elif COMPILER3

#warn

#else

#error Compiler not supported.

#endif

Not only does this litter the code – it is also a maintenance nightmare.

Usually, the solution is to encapsulate compiler specific features in #defines; alas this obvious strategy doesn’t work for #pragmas:

1

2

#define WARNINGS_ON #pragma nowarn -save // doesn't work

#define WARNINGS_OFF #pragma nowarn -restore // doesn't work

So it is time to roll out our trick once again:

1

2

3

4

5

#include "warnings_off"

...

// Nasty code

...

#include "warnings_on"

Where, for instance, “warnings_off” looks like this:

1

2

3

4

5

6

7

8

9

10

// warnings_off

#if COMPILER1

#pragma warning off

#elif COMPILER2

#pragma nowarn -save

#elif COMPILER3

#nowarn

#else

#error Compiler not supported.

#endif

You probably won’t need this trick very often, but when you do, it is good to know that it’s there.