简体   繁体   中英

Trouble with macros in C

I'm having trouble with Macros in C. I tried reading some material, but it is going over my head.

For example:

#include <stdio.h>

#define A(x) ((x)?-1:0)

int main()
{
    int i = 2;
    int i2 = A(i)*i;
    printf("%d", i2);
    return 0;
}

Can someone comment on that code so I know what is happening? Or if you have links to similar exercises with commented code I could learn from that would be great.

After the macro has been expanded, the i2 line will look like:

int i2 = ((i) ? -1 : 0) * i;

I assume the double equals is a typo.

And since the value of i is 2 , the above will take the first part of the ternary expression, and evaluate -1 * 2 which is of course -2 .

One idea is to run the code through a preprocessor, and look at the result. With gcc , the relevant command-line option is -E .

First, you have a syntax error. This:

int i2= = A(i)*i;

Should be this:

int i2 = A(i)*i;

With that fixed, A here is a function macro. It takes its argument and substitutes it into the macro expression.

So this:

int i2 = A(i)*i;

Gets substituted for this:

int i2 = ((i)?-1:0)*i;

This: ?: is the ternary operator. It first evaluates the first expression. If that expression evaluates to true (ie non zero), the second expression is evaluated, otherwise the third expression is evaluated.

Since i is equal to 2, the ternary evaluates to true, so ((i)?-1:0) evaluates to -1. This is then multiplied by i (which is 2) to give us -2, which is then assigned to i2 .

int i = 2;
int i2=A(i)*i;             // statement after correction

i2 will have value -2 ,as after expansion statement would be -

int i2=((i)?-1:0)*i;      // condition is checked 

As i ( a positive integer ) is not 0 therefore , condition is true and it evaluates in -1 and then -1*i ie -1*2 , thus i2 is -2 .

Note - Right now this statement is incorrect -

int i2= = A(i)*i;
      ^^^ use assignment operator not == 

can someone comment on that code

Sure. I think that macro expansion is confusing:

1 A(i) in example above is A(2) .

2 A(2) expands to 2?-1:0

3 2?-1:0 is equal -1 because 2 is not 0 (explanation of ? is here: What does ? in C mean? )

Anyway I hope you know it's not a good code. ;)

#define A(x) ((x)?-1:0)

is in format of

var = boolean_condition ? if_true : if_false;

this is the compact format of this one:

if ( boolean_condition )
     var = if_true;
else
     var = if_false;

in your case

int i2 = A(i)*i;

the compiler will expand the macro to

int i2=((i)?-1:0);

and since i <> 0 then i2 = -1;

"Can someone comment on that code so I know what is happening?"

Before I comment, let's let the C-Preprocessor clarify what is happening. The C Preprocessor is in charge of expanding your macros into your code before actual compilation of your code takes place (it is also responsible for handling the #include at the top of your program). Running your main() function through the C Preprocessor the output is:

int main()
{
    int i = 2;
    int i2 = ((i)?-1:0)*i;
    printf("%d", i2);
    return 0;
}

As you can see, the C preprocessor has expanded your macro on the second line of your main function. So now let's comment on your code:

  • Line 1: Assign the value 2 to int variable i.
  • Line 2: Any non-zero integer will result in a "true" if statement (go ahead, write a program and see for yourself!). The ternary operator grammar is:

    RESULT = (conditional) ? (EXPRESSION IF TRUE) : (EXPRESSION IF FALSE)

    Since the conditional (2) evaluates True, the macro will return -1. Then it will multiply i by -1, resulting in -2.

I'm pretty sure lines 3 and 4 are self-explanatory at this point.

Are you programming in an IDE or on the command line? I would highly recommend you use the command line, or at least be able to use it when needed. For example you can run your code through the c preprocessor on the command line by running either

cpp <your-program-name>.c

or (if using GNU C compiler)

gcc -E <your-program-name>.c

You'll be able to see what's going on "under the hood" a lot more easily. An IDE tries to hide these details from you, for reasons good or bad. But in C, the little details really do matter, as you've chosen to work with a low-level yet very powerful language. For which I applaud you.

Also take advantage of the C-faq ( http://c-faq.com ) website. In particular, take a look at the C Preprocessor FAQ . Please comment if I can clarify anything I have said.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM