Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For loop in #define

#include <stdio.h>
#define UNITS {'*', '#', '%', '!', '+', '$', '=', '-'}

#define PrintDigit(c, d) (for (i=0; i < c ; i++)putchar(unit[d]);)

char unit[] = UNITS;

//void PrintDigit(c, element) {
//  int i;
//  for (i=0; i < c ; i++)
//      putchar(unit[element]);
//}


int main( ) {
    int i, element=4;
    PrintDigit(10, element);
    putchar('\n');
    return 0;
}

I have the function here PrintDigit() which works as expected. When attempting to turn the function into a #define however gcc keeps throwing a syntax error on the for loop. Any idea what the problem is?

like image 994
hspim Avatar asked Jan 23 '23 08:01

hspim


2 Answers

You've enclosed the for loop in parenthesis, which you need to remove.

Change

#define PrintDigit(c, d) (for(i=0; i < c ; i++)putchar(unit[d]);)

to

#define PrintDigit(c, d) for(i=0; i < c ; i++)putchar(unit[d]);

EDIT:

The reason for this is that the C grammar does not allow a statement (iterative statement in this case) to be inside parenthesis but allows an expression.

You can take a look at the C grammar here.

like image 194
codaddict Avatar answered Feb 01 '23 14:02

codaddict


This is a terrible idea... you should just make it an inline function. However, the problem is that you have surrounded your definition in parentheses which makes it incorrect. Remove the parentheses and also remove the semicolon at the end (so that you can place a semicolon after it), and it should work.

In other words, change your definition to:

#define PrintDigit(c, d) \
    for (int i = 0; i < c ; i++) \
        putchar(unit[d])

You can make this a little bit less fragile by putting it in an inner scope:

#define PrintDigit(c,d) \
     do{\
         for (int i = 0; i < c; i++ ) { \
             putchar(unit[d]); \
         }\
     }while(0)
like image 26
Michael Aaron Safyan Avatar answered Feb 01 '23 13:02

Michael Aaron Safyan