Macros with Variables

Some C coders really go nuts with macros. I’m not a big fan of those people.

The C language is obscure enough. When you add to that obscurity the use of macros, it makes a difficult language even more incomprehensible. Yet, some coders revel in that obfuscation.

A few Lessons back, someone asked me to describe how a loop works. I committed the terrible sin of actually explaining how a for loop did its job. They just wanted to know, “Okay, so I need to repeat a chunk of code ten times.” That’s the kind of statement you get from a student who is required to take a programming course but doesn’t give a damn about learning anything.

Anyway, the C language lacks a direct looping keyword, but you can define one as a macro, which I did in this code example:

#include <stdio.h>

#define repeat( c ) for(int c1=0;c1<c;c1++)

int main()
{
    repeat(10)
    {
        puts("Hello!");
    }

    return(0);
}

The #define preprocessor directive at Line 3 sets the repeat() macro equal to a standard for loop. Variable c from the repeat macro is placed into the for loop at the proper locations to make a simple loop. Another variable, integer c1, is created inside the for statement with int c1=0. That’s perfectly legal, providing that the variable isn’t declared elsewhere in the code.

The end result of the macro is seen in the main() function: The repeat() “function” processes a series of statements a given number of times. This kind of trick wouldn’t work with a true function; only a macro can set up such a statement within your code.

Another way to define the macro would be as follows:

#define repeat( c ) int c1 ; for(c1=0;c1<c;c1++)

Above, the repeat macro is expanded into two statements. The first declares the int variable c1. The second is the for loop that uses variable c1 as well as variable c. The program output is the same. My point is to demonstrate that a #define macro can include more than a single statement. And that’s where things can get even more confusing.

My advice is to use #define to create constants, which is common and expected. When you use #define to shorten tangled code, that might be another good use, but my advice is to pull back on creating new function-like macros and otherwise obfuscating the text. While such antics may impress hard core C programmers, the end result is difficult to document and debug.

Leave a Reply