2

I was reading this tutorial of stanford where they say :

Common coding mistakes:

Bad parentheses in macro definition

#define min(a, b) a<b?a:b // incorrect
#define min(a, b) (((a)<(b))?(a):(b)) // correct

I even ran this in a program, It worked fine.

Can anybody explain what they are trying to say!

Gaurav Arora
  • 183
  • 2
  • 10
  • 1
    Either form is bad. The proper way to do this is `int min (int a, int b) { return a – Lundin Apr 26 '16 at 10:43
  • 1
    You have to consider that macros are not functions, they literally just replace the text you define, so if you are going to use them in more complex situations, as someone has already pointed out, you could find some problems –  Apr 26 '16 at 13:36
  • Possible duplicate of [The need for parentheses in macros in C](https://stackoverflow.com/questions/10820340/the-need-for-parentheses-in-macros-in-c) – phuclv Aug 03 '17 at 16:40
  • Does this answer your question? [C macros and use of arguments in parentheses](https://stackoverflow.com/questions/7186504/c-macros-and-use-of-arguments-in-parentheses) – Nate Eldredge Sep 25 '20 at 03:49

1 Answers1

4

The first version fails if you combine it with other operators:

min(a , b) + c 

and translates to:

a<b?a:b+c 

which is identical to:

a<b?a:(b+c) 

which is an unexpected outcome given the starting parenthesis.

The second version isn't much better. It evaluates one of the parameters twice which can cause unexpected behavior if a function or i++ is passed to the macro.

An inline function should be used instead of those macros.

2501
  • 25,460
  • 4
  • 47
  • 87
  • 2
    "It evaluates one of the parameters twice which can cause undefined behavior" No this is not correct for this specific case. There is a sequence point between the evaluation of the 1st and the 2nd or 3rd operand. – Lundin Apr 26 '16 at 10:44
  • the unexpexted behaviour,if i++ is passed, is because of the ternary operator being there, right? or it has to do something with macro..? – Gaurav Arora Apr 26 '16 at 10:46
  • @GauravArora No, it is because function-like macros in general are unsafe and very bad practice. – Lundin Apr 26 '16 at 10:46
  • @Lundin Thank you. I have fixed the answer. – 2501 Apr 26 '16 at 10:48
  • @Lundin If is use ternary operator in a function and pass i++ to it, won't that lead to undefined behaviour? – Gaurav Arora Apr 26 '16 at 10:48
  • @GauravArora It depends on the caller code. Code like `min(i, i++)` will invoked undefined behavior, but code like `min(x, i++)` will not. – Lundin Apr 26 '16 at 10:49
  • @GauravArora Only if you pass `min(i,i++)` which is obviously wrong. But i++ might be evaluated twice depending on the result of the comparison giving unexpected results. – 2501 Apr 26 '16 at 10:49
  • Okay , but what's wrong with macro then? we're using the same ternary operator at both places, – Gaurav Arora Apr 26 '16 at 10:51
  • yeah, I did, :), but I'm asking why is it doing this? – Gaurav Arora Apr 26 '16 at 10:53
  • @GauravArora Because that is how the language and its operator is defined. – 2501 Apr 26 '16 at 10:54
  • 1
    @GauravArora A function-like macro has no type safety, it can cause precedence bugs (which is what your tutor is hinting at) it allows any kind of side effects to get passed on, they are hard to read, hard to debug, hard to maintain. Function-like macros are always the last resort when you have tried everything else. – Lundin Apr 26 '16 at 10:54
  • Okay, Thankyou 2501 , Lundin :) – Gaurav Arora Apr 26 '16 at 10:55