Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Removed an incorrect statement about undefined behavior.

...

Code Block
bgColor#FFcccc
langc
#define ABS(x) (((x) < 0) ? -(x) : (x))

void f(int n) {
  int m;
  m = ABS(++n); /* undefined behavior */
  /* ... */
}

The invocation of the ABS()macro in this noncompliant code example expands to the following code. Since the resulting expression modifies an object more than once, its behavior is undefined. (See EXP30-C. Do not depend on order of evaluation between sequence points.)The resulting code has well-defined behavior, but causes n to be incremented twice rather than once, which may be surprising to those unfamiliar with the implementation of the macro, or unaware of the fact that they are using a macro in the first place.

Code Block
bgColor#FFcccc
langc
m = (((++n) < 0) ? -(++n) : (++n));  /* undefined behavior */

Anchor
cs_inline_function
cs_inline_function

...

A possible and preferable compliant solution is to define an inline function with equivalent but safe unsurprising semantics:

Code Block
bgColor#ccccff
langc
inline int Abs(int x) {
  return x < 0 ? -x : x;
}

...

Code Block
bgColor#ccccff
langc
#define ABS(x) ({int__typeof (x) tmp = (x); tmp < 0 ? -tmp : tmp; })

...