Why the following function is called thrice

后端 未结 6 1268
轻奢々
轻奢々 2021-01-20 10:45

I had tried to debug but no luck I can\'t understand why the second printf() is call increment() thrice but the first one call twice as expected.

#include &l         


        
相关标签:
6条回答
  • 2021-01-20 11:31

    Use of macros is highly "dangerous": all sort of strange things can happen. For instance, in your case, if you call MAX( f(), g() ) the function which gives you the greatest result gets called twice, the other one gets called just once. Since you are using MAX(x, f()), f gets called twice if and only if it gives a result which is greater than x.

    In particular, the macro expands as

     ( (x) > (increment())? (x):(increment()) )
    

    so that if the condition (testing which requires one evaluation of increment(), increment() gets executed in order to produce the result.

    0 讨论(0)
  • 2021-01-20 11:32

    Because you tell it so:

    MAX(x, increment())
    

    evaluates to

    ( (x) > (increment()) ? (x) : (increment()) )
    

    and if the condition is not fulfilled, the part after the : is evaluated and thus the function called again.

    0 讨论(0)
  • 2021-01-20 11:33

    This is a classic example of side effects in macros. Your max macro examples out to this:

    x > increment() ? x : increment()
    

    Once the return value from increment() if bigger than x the ternary operator will call increment() twice, once to evaluate the condition and once to evaluate the false part (which is the second increment()).

    In this case you're best best is to max max_int function:

    int max_int(int a, int b)
    {
      return a > b ? a : b;
    }
    

    Calling this instead of MAX will ensure your arguments are only ever evaluated once.

    0 讨论(0)
  • 2021-01-20 11:33

    ( (a) > (b) ? (a) : (b) )

    In this statement, if b stands for a function, it will be called just once if (a > b) is true, but twice if (a > b) is false: one to give parameters for the comparison(b in "(a) > (b)"), the other to return a value for the whole statement(b in the latter part of the macro).

    In your case, there's an extra call of "b"(increment) to provide the second integer parameter in each test.

    Altogether, its twice and thrice.

    0 讨论(0)
  • 2021-01-20 11:35

    This happens because your macro will expand as ( (x) > (increment()) ? (x) : (increment()) ).

    However, this is not the only problem, your code contains undefined behaviour. Parameters are not evaluated in a specified order.

    0 讨论(0)
  • 2021-01-20 11:43

    Because macro: MAX(x, increment()) expands as:

    ( (x) > (increment()) ? (x) : (increment()) )
    

    Similarly next call of macro expands.

    Variable i is static so initially initialized with i = 42, and its incremented value persists in different function calls.

    below a sequence of function call shown with values of i returned by increment() function.

     increment();    i = 47, First call
    
       x      52       x     i       
    ( (50) > (52) ? (50) : (52) ) 
            Second        // ^ not called because condition is True 50 > 52
    

    second time:

        increment();   i = 57, Third call
    
         x      i       x      i         
      ( (50) > (62) ? (50) : (67) ) 
              Forth          Fifth   // called because condition is False  50 > 62
    

    This sequence is according to your output.

    Important to note you may be different output with different compilers because the order of evaluation of function arguments are undefined of Undefined behavior.

    http://www.stroustrup.com/bs_faq2.html#macro

    0 讨论(0)
提交回复
热议问题