Incorrect expansion of a function-like macro

2020-04-21 02:01发布

问题:

Good evening,
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
}

回答1:

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.)