ESP-32 compiler bug

A new error appeared when compiling code using the MF_MIDIfile library. I condensed the code to a simple program which exhibits the problem.

typedef struct
{
  uint8_t track;    ///< the track this was on
  uint16_t size;    ///< the number of data bytes
  uint8_t type;     ///< meta event type
  union
  {
    uint8_t data[50]; ///< byte data. Only 'size' bytes are valid
    char chars[50];   ///< string data. Only 'size' bytes are valid
  };
} meta_event;
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))

void setup(void)
{
 uint32_t mLen;
 meta_event mev;
 mLen = 12;
  uint8_t minLen = min(ARRAY_SIZE(mev.data), mLen);
}
void loop(void){
}

If you compile this code for the Arduino Nano ESP32 it gives no error.
If you select the "ESP32 Dev Module", the "ESP32-WROOM-DA module", or the "DOIT ESP32 DEVKIT V1" (and probably others), it compiles with the following error (plus much more):

D:\Util\ArduinoSB\Sketchbook\MF_error\MF_error.ino:23:23: error: no matching function for call to 'min(unsigned int, uint32_t&)'

I am using IDE 2.3.4.

The Dispatcher

Hi @thedispatcher. When compiling for ESP32, both arguments to min must have the same data type:

So you can fix the error by changing this line:

uint32_t mLen;

To this:

unsigned int mLen;

Interesting. The severity of the issue appears to vary with version of ESP32 Arduino Core. Anyway, since sizeof() produces type size_t, best would be:

	size_t mLen;

You can also provide the template parameter to std::min. This will allow for implicit conversion of the argument types because the template no longer needs to be deduced.

  uint32_t mLen;
  meta_event mev;
  mLen = 12;
  uint8_t minLen = min<size_t>(ARRAY_SIZE(mev.data), mLen);

Where would std:min be placed?

The suggestions are welcome. I have only 2 slight misgivings:

  1. I don't like having to change the code of a published library.
  2. "min()" is documented to accept parameters of any type. Should this be changed?

Thanks for the very prompt attention.
The Dispatcher

On ESP32, min() invokes std::min() from the Standard C++ Library (at least it does with ESP32 Arduino Core 3.07 where I tested it). So, the code in Post #4 works as-is.

Any is an overly-strong statement. First, as @ptillisch noted, both parameters must be of the same type. Second, there must actually be a function available that determines which is greater ... min(Serial, Serial1); would be nonsense. You could say without argument that it works for all numeric types ... as long as both are the same type.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.