Skip to content

Core library defines min, max, abs and friends as macros which may cause unexpected side effects #2069

Open
@ghost

Description

Suppose you pass an argument of a function call which has a side effect as an argument to abs() like this:

int f() { /* do some nasty things */ }

void loop() {
  ...
  int b = abs(f());
  ...
}

The abs() is defined in the Arduino.h as:

#define abs(x) ((x)>0?(x):-(x))

It is easy to see, that the function will be evaluated 2 times. Moreover, if a volatile variable is passed as an argument to such macro and the value of the variable gets changed by an interrupt handler, the result will also be unpredictable. What if the argument is a complex expression? Will the code optimization help to prevend a second evaluation of the expression? IMHO that is a good question to ask.

Using macro arguments in macro body more that 1 time is misleading and dangerous. In fact users of Arduino IDE has no way of looking into the source code to see a potential problem.

You should really review the folowing macros and either rewrite them as inline functions or document the side effects:

  • min(a,b)
  • max(a,b)
  • abs(x)
  • constrain(amt,low,high)
  • round(x)
  • sq(x)

Metadata

Metadata

Assignees

Labels

Component: CoreRelated to the code for the standard Arduino API

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions