Skip to content

Error with _min and _max macro #7244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
6 tasks
warnerthuis opened this issue Apr 23, 2020 · 6 comments
Closed
6 tasks

Error with _min and _max macro #7244

warnerthuis opened this issue Apr 23, 2020 · 6 comments
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.

Comments

@warnerthuis
Copy link

warnerthuis commented Apr 23, 2020

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [2.6.3]
  • Development Env: [Arduino IDE]
  • Operating System: [Windows]

Settings in IDE

  • Module: [Generic ESP8266 Module]
  • Flash Mode: [qio|dio|other]
  • Flash Size: [4MB/1MB]
  • lwip Variant: [v1.4|v2 Lower Memory|Higher Bandwidth]
  • Reset Method: [ck|nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz|160MHz]
  • Upload Using: [OTA|SERIAL]
  • Upload Speed: [115200|other] (serial upload only)

Error with _min and _max macro

I have code which uses the _max and the _min macro. They are in the Arduino.h library.
That compiles ok with version 2.4.0 of the library where the definition of the maro's is:

#define _min(a,b) ((a)<(b)?(a):(b))
#define _max(a,b) ((a)>(b)?(a):(b))

Now in version 2.6.3 the definition is:

#define _min(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a < _b? _a : _b; })
#define _max(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a > _b? _a : _b; })

And the errors are:

C:\Users\warner\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266/Arduino.h:254:85: internal compiler error: in cp_parser_abort_tentative_parse, at cp/parser.c:23793
 #define _min(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a < _b? _a : _b; })
    pointer under ; after _b = (b)   ^

C:\Users\warner\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\cores\esp8266/Arduino.h:255:53: note: in definition of macro '_max'
 #define _max(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a > _b? _a : _b; })
   pointer under ; after _a = (a)           ^

MCVE Sketch

#include <Arduino.h>

void setup() {
  float op = 50;
  float ophi = 100;
  float oplo = 0;
  op = _max(oplo, _min(ophi, op));

}

void loop() {

}

Debug Messages

Debug messages go here
@d-a-v
Copy link
Collaborator

d-a-v commented Apr 23, 2020

The new code in 2.6.3 is better than before (macro arguments can be reevaluated and this is bad).
You can replace these macro by std::min and std::max but they may not be usable in other arduino archs.
An internal compiler error is hard to reproduce.

Until we have gcc9.3, I suggest you add this in your code :

#ifdef ESP8266
#undef _min
#undef _max
//#define _min(a,b) ((a)<(b)?(a):(b))
//#define _max(a,b) ((a)>(b)?(a):(b))
#define _min(a,b) std::min(a,b)
#define _max(a,b) std::max(a,b)
#endif 

Alternatively you can try alpha version 0.0.2 of this core that already has gcc9.3.

@warnerthuis
Copy link
Author

thanks, I'll try

@devyte
Copy link
Collaborator

devyte commented Apr 23, 2020

For user code, it is strongly advised to use std::max/std::min, and not the macros.
The original macros you mention have a bug, where if you pass in anything that could have a side effect, you'll have the side effect evaluated twice.
The new macro improves on that by making a temporary local, which should then get optimized away, but such preprocessor macros are far from ideal. especially when it comes to casting.
In contrast, the standard std::min/std::max force same-type calculation without multiple side effects, and if you want to cast, you have to do so on purpose (which makes you think about what you're doing).

@devyte
Copy link
Collaborator

devyte commented May 16, 2020

@warnerthuis did you try the std min/max?

@devyte devyte added the waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. label May 16, 2020
@warnerthuis
Copy link
Author

warnerthuis commented May 18, 2020

sorry for not mentioning that I used successfully the std min/max aproach. I was too busy with other projects (node-red). It works now in the new version.

@arbourp
Copy link

arbourp commented Nov 10, 2021

Wanted to leave a comment to follow-up here.
I ran into a very similar error while using the DMXInputNeoPixel demo from the LXESP8266UARTDMX library.

Oddly enough there is a comment saying that 'min' may fail so they used _min instead. pionting to this issue #263

At this point in time with 3.0.2 version of the esp8266 code I get
/STORAGE/home/megatron/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/cores/esp8266/Arduino.h:243:19: error: statement-expressions are not allowed outside functions nor in template-argument lists

So I modified the code in the DMXInputNeoPixel demo to use 'min' instead of '_min' and it compiles fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

No branches or pull requests

4 participants