1

The code below explain how the x macros works in a simple way in c programming langauge

#include <stdio.h> 

// Defines four variables. 
#define VARIABLES \ 
    X(value1, 1)  \ 
    X(value2, 2)  \ 
    X(value3, 3)  \ 
    X(value4, 4) 

// driver program. 
int main(void) 
{ 
    // Declaration of every variable 
    // is done through macro. 
    #define X(value, a) char value[10]; 
        VARIABLES 
    #undef X 

    // String values are accepted 
    // for all variables. 
    #define X(value, a) scanf("\n%s", value); 
        VARIABLES 
    #undef X 

    // Values are printed. 
    #define X(value, a) printf("%d) %s\n", a, value); 
        VARIABLES 
    #undef X 
    return 0; 
} 

Form the definion of the macros in c. it is just a text replacement tool. so the compiler will recreate the code in the following way below:

#include <stdio.h> 

int main(void) 
{ 
    char value1[10]; 
    char value2[10]; 
    char value3[10]; 
    char value4[10]; 

    scanf("\n%s", value1); 
    scanf("\n%s", value2); 
    scanf("\n%s", value3); 
    scanf("\n%s", value4); 

    printf("%d) %s\n", 1, value1); 
    printf("%d) %s\n", 2, value2); 
    printf("%d) %s\n", 3, value3); 
    printf("%d) %s\n", 4, value4); 
    return 0; 
} 

The preprocessor will replace

VARIABLES ------> X(value1, 1) X(value2, 2) X(value3, 3) X(value4, 4)

And it will replace X(value1, 1) with char value[10]; in the following way

X(value1, 1)      char value[10];
  -----                -----
    v                    ^
    |                    |
    +--------------------+

//how the code become like this ?

 char value1[10];

//why not like this?

char value[10]1;

//or like this?

char value[10];1

//why the macro consider value as the text and place 1 immediately after it?

And what about the second argument 1, is it going to be replaced with something?

X(value1, 1) 
         ---             
          ^                    
          |                    
//where is this parameter replaced with    
Lundin
  • 195,001
  • 40
  • 254
  • 396
Haider
  • 13
  • 4
  • 2
    Please **DON'T** tag with every single C tag in existence. If you are talking about C, only tag with `c`. If you are talking about a specific version, then tag that version *only*. – Marco Bonelli Apr 22 '20 at 10:20
  • It's not clear at all what you're asking about. You have the result, so what is it about it that you don't understand? – molbdnilo Apr 22 '20 at 10:22
  • Thanks for informing me. I will do in the future. – Haider Apr 22 '20 at 10:23
  • I make some updates in the post. I don't understand the way how the text replaced. please check the post again! – Haider Apr 22 '20 at 10:24
  • I don't understand. `#define X(value, a) char value[10];` and `X(value1, 1)` - why would you ever expect `char value[10]1;`? `why the macro consider value as the text and place 1 immediately after it?` Yes. Macros operate on text only. – KamilCuk Apr 22 '20 at 10:25
  • But `value1` is not the same as `value`. It should not be replaced becasue it does not match each other. Why only took the number 1 from `value1` and replace it with `value` – Haider Apr 22 '20 at 10:29
  • Well, no. If I would do `#define abc xyz` and write `abcdef` then it would __not__ replace "part of the string". `1` in `value1` is part of `value1`, it's not separate. It's a whole token. `But value1 is not the same as value` when you have `#define X(value, a) ..` and do `X(value1, anything)` then the token `value` is replaced by `value1`. `Why only took the number 1 from value1` nothing is "taken" from "value1". – KamilCuk Apr 22 '20 at 10:30
  • I do not follow, it's a string replacement. You have `#define X(value, a) char value[10]; ` and you run `X(value1, 1)`. That means we replace the token `value` for the string `value1` and the token `a` for the string `1` in the string `char value[10];`. So, in the string `char value[10];` there is one token `value` in the middle, so it get's replaced for `value1`. The ascii graphic you present is the best explanation I have seen - you take the string `value1` and put it in place for `value` in the replacement string. – KamilCuk Apr 22 '20 at 10:36
  • great expalantaion KamilCuk, now I understand about the value token repalcement thanks alot. now the difficult part becasue about the second parameter ` 1 ` in `X(value1, 1)` – Haider Apr 22 '20 at 10:42
  • Btw "macros is just text replacement" is a simplification. They are rather "pre-processor token replacement", you can't pass any random text to a macro, it has to be a valid pre-processor token. – Lundin Apr 22 '20 at 10:49
  • You seem to get confused by the fact that `value1` and `value` are similar. Try to use `#define X(peter, tom) char peter[10]` and then use `X(John1,99)` Would you also expect to get `char John[10]1;` ? – Gerhardh Apr 22 '20 at 10:53
  • @Gerhardh, thanks for that. Everthing now is clear about the token replacement part. – Haider Apr 22 '20 at 10:58

1 Answers1

0

In #define X(value, a), the value and a are macro parameters. If you pass X(value1, 1) then those will become the values of these macro parameters, kind of like when you pass parameters to a function.

In the case of #define X(value, a) char value[10];, the parameter a isn't used in the macro so it is just ignored.

This is common when using X macros, you might have several values but only some that make sense to use in a specific case. You will still have to pass all parameters, but using them in each macro is optional.

It works just like plain old functions. This function is perfectly valid:

void foo (int a, int b)
{
  printf("%d", a);
}

Where did b go? Nowhere, the function simply did not use it.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thanks @Lundin for the explanation. What I don't understand was that the macro ignore the unused parameter. now everthing is clear. – Haider Apr 22 '20 at 10:57
  • @Haider These X macros often end up like that because you've already forced them to always use 2 parameters with the list like `X(value1, 1)`. I suppose you could optionally write `#define X(value, ...) char value[10];` and that will work just as fine, but it might just add more confusion. – Lundin Apr 22 '20 at 10:59
  • what is that mean when we are saying "macro names are negotiable". according to this answer [link](https://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value/9812815) – Haider Apr 23 '20 at 02:20
  • @Haider It simply means that you can name your macros whatever you like...? – Lundin Apr 23 '20 at 06:31
  • that was clear thanks. becasue english is not my first langauge I couldn't understand "negotiable". – Haider Apr 23 '20 at 07:17