Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect expansion of a function-like macro

I have a problem with macros. I am supposed to come up with a macro ENTRY, that puts a value into an array ( scanf("%d",&ENTRY(x,i)) was given).

I tried: #define ENTRY (a,b) (a[b-1]), but that didn't work.
It created a compiler error that says, that a and b are undeclared.
But I thought that I don't have to declare variables used in macros, especially because, for example: #define min(a,b) ((a)<(b)?(a):(b)) worked in another program.

So what am I doing wrong here?

#include <stdio.h>
#define N 3
#define ENTRY (a,b) (a[b-1])

int main(void)
{
    
    int x[N],i;
    float y[N];

    for(i=1;i<=N;i++){ printf("x_%d = ",i);scanf("%d",&ENTRY(x,i));}
    for(i=1;i<=N;i++){ printf("y_%d = ",i);scanf("%lf",&ENTRY(y,i));}

    return 0
}
like image 753
vincent.perl99 Avatar asked Dec 28 '25 22:12

vincent.perl99


1 Answers

Function-like macro definitions can't have whitespace after the macro name

#define ENTRY (a,b) (a[b-1])              // wrong

=>

#define ENTRY(a,b) ((a)[(b)-1])               // correct

6.10 – Preprocessing directives:

...

control-line:
...

# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line

...

lparen:
a ( character not immediately preceded by white-space

With the space, you get an object-like macro that expands to (a,b) (a[b-1]).

(For additional robustness, it's also recommended to parenthesize the parameters so that it also works if you pass in more complex expressions.)

like image 176
PSkocik Avatar answered Dec 31 '25 13:12

PSkocik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!