0

I was learning the use of token parsing operator. When I did as follows,

#include <stdio.h>

#define concat(a, b) a##b

int main(int argc, char** argv)
{
    printf("%d\n", concat(1, 2));
    system("pause");
    return 0;
}

Output : 12

But when I tried to pass arguments as variable name,

#include <stdio.h>

#define concat(a, b) a##b

int main(int argc, char** argv)
{
    int x = 2;
    int y = 3;
    printf("%d\n", concat(x, y));
    system("pause");
    return 0;
}

Got error

'system' undefined; assuming extern returning int   
'xy': undeclared identifier
identifier "xy" is undefined

I read in Stackoverflow as "C macros are really preprocessor macros that are expanded before compilation. The variable 'port', doesn't get set until runtime."

Okay, That's not possible. But when I tried this

#include <stdio.h>

#define mult(a, b) a*b

int main(int argc, char** argv)
{
    int x = 2;
    int y = 3;
    printf("%d\n", mult(x, y));
    system("pause");
    return 0;
}

OUTPUT : 6

Why this has no error, but with ## there's error

Community
  • 1
  • 1
Athul
  • 429
  • 2
  • 5
  • 19
  • 2
    Because `mult(x, y)` is replaced by `x*y`, which is a legit expression. – Ely Jun 17 '18 at 14:50
  • 3
    If you use the `gcc` compiler, try running `gcc -E test.c >processed.c` to see what the `##` operator does. (Maybe remove the `#include ` header to reduce clutter.) – David Collins Jun 17 '18 at 14:57
  • 3
    Think of the preprocessor as a separate program, which works on a text stream which may or may not be a C program. The preprocessor does not know C, it does not care about C language syntax or semantics. All it knows is to read text and do some substitutions. The C compiler proper sees only what comes out of the preprocessor. In you examples, the C compiler sees first `xy` and flags an undeclared variable, and then `x*y` which is an ordinary expression. – AlexP Jun 17 '18 at 14:59
  • @AlexP `printf("%d\n", mult(x, y));` this line after preprocessing become `printf("%d\n", x*y);` or `printf("%d\n", 2*3);` Which is correct? – Athul Jun 17 '18 at 15:23
  • @Athul: *The preprocessor does not know C*. As far as the preprocessor is concerned the source text is just text. (You can actually run the C preprocessor or arbitrary text; sometimes this is quite useful.) *It does not understand that `int x = 2;` assigns the value 2 to the variable `x`.* So after preprocessing the line reads `printf ("%d\n", x*y);`. – AlexP Jun 17 '18 at 15:31
  • The pre-processor replaces `mult(x, y)` by `x*y`, which then gets fed to the compiler. – alk Jun 17 '18 at 16:11

1 Answers1

3

Preprocessor doesn't know the C language.

Preprocessor is STUPID. It does not run your program. It just takes the code and mechanically applies changes which you tell him to apply. This changed code is compiled by C compilier.

when you write

#define concat(a,b) a##b
...
int x=2, y=3;
int z=concat(x,y);

It does NOT run the program to determine that x=2, y=3. For preprocessor, int x=2, y=3; is just a silly sequence of tokens whose meaning it doesn't understand. It doesn't even know that x and y are variables. It just knows that concat means concatenation of two tokens. So it produces the code:

...
int x=2, y=3;
int z=xy;

Which then goes to the C compilier.

user31264
  • 6,557
  • 3
  • 26
  • 40