arduino / arduino/Arduino

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

Open
#2,069 11 comments 2 reactions 1 assignee Claimed by @cmaglie View on GitHub
Component: Core
Dominant language
Java
Stars
14.6k
Forks
7k
PR merge metrics
No merged PRs in 30d

Description

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

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

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

The _abs()_ is defined in the _Arduino.h_ as:

``` C
#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)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.