Click here to Skip to main content
15,880,891 members
Articles / Programming Languages / Visual C++ 10.0
Tip/Trick

Pre-processor Iteration

Rate me:
Please Sign up or sign in to vote.
4.64/5 (8 votes)
19 Nov 2012CPOL2 min read 36K   186   7   6
Emulating iterative structures with the C++ pre-processor.

Introduction

The C++ preprocessor is probably the most ubiquitous text transformation tool out there. However, it has its drawbacks. For one, it does not let you iterate. I often wish for a #for(...) directive to complement the #if(..). This is specially useful for writing repetitive code that follows a pattern.

Fortunately, there is a way around this. I discovered this when I accidentally #included a file from within the same file. The compiler complained of infinite recursion. Voila! The preprocessor supports recursive includes! The only other piece to this puzzle is an index variable which can be modified.

Here is where it gets ugly. Preprocessor variables can not be incremented/decremented using the usual arithmetic operators. In other words, the following is illegal: 

C++
#define ITER 0
ITER = ITER+1

However, a similar result can be obtained using brute force: 

C++
#if(ITER == 0)
#undef ITER
#define ITER 1
#elif(ITER == 1)
#undef ITER
#define ITER 2
#endif

This can be continued for as many iterations as will be needed.

Putting it all together

The source code for this is hosted on github: 

https://github.com/debdattabasu/pp_Iteration

Basically, the code defines an iterator that is incremented as discussed above. The file loop.h keeps including itself until the iterator reaches a specified value.

Make sure to check out the code sample for details.

Use Cases

  1. Loop Unrolling: Most modern compilers can do this for standard loops. However, some low-end embedded compilers can't. A good example of this is the GLSL compiler found in many embedded GPU drivers.
  2. Emulated Arrays: This is another issue I had to face while writing GLSL. Older versions of OpenGL do not support arrays of textures. Hence, I had to do things like this:
  3. C++
    uniform sampler2D  Tex_01 ;
    uniform sampler2D  Tex_02 ;
    uniform sampler2D  Tex_03 ;
    uniform sampler2D  Tex_04 ;

It is much easier to automate this with preprocessor iterations.

Using the Code 

To demonstrate how preprocessor iterations work, we create code to print numbers less than 10. The looping is done at compile time, and there is no runtime overhead.

C++
int main()
{
    #include "loopstart.h"
        #define LOOP_END 10
        #define MACRO(x) printf("%d\n", x);
    #include "loop.h"
    return 0;
}

Basically, we have to do the following:

  • Include loopstart.h
  • Define LOOP_END to be the number of required iterations
  • Define MACRO(x) to be the code fragment that is repeated. X is the loop counter.
  • Include Loop.h 

We could, of course, add more bells and whistles to this, like a starting point for the iterator other than the default 0. This is pretty easy to do once you get a hang of the general concept, and is left as an exercise for the reader. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student Indian Institute of Technology, Roorkee
India India
Debdatta Basu is a student at Indian Institute of Technology, Roorkee, currently pursuing his Bachelor's Degree in Electronics and Communication Engineering. He has four years of experience with C++, C#, Computer Graphics, and Parallel Programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
dgthiyagu24-Aug-12 7:41
dgthiyagu24-Aug-12 7:41 
GeneralRe: My vote of 5 Pin
Debdatta Basu27-Aug-12 21:56
Debdatta Basu27-Aug-12 21:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.