toInt works for MEGA but not working for ESP8266

I compile the following code for board “Arduino/Genuino Mega or Mega 2560” with no problem:

byte          myByte;
unsigned long myLongInt;
String        myParameter = "5";

void setup() {
  myLongInt = myParameter.toInt();
  myByte    = max(5, myParameter.toInt());
}

void loop() {
}

When I compile the code for board “WeMos D1 R1” the myLongInt statement compiles fine but the myByte statement gives the following very long error report:

C:\Users\Ron\Documents\Arduino\sketch_apr18b\sketch_apr18b.ino: In function 'void setup()':

sketch_apr18b:7:41: error: no matching function for call to 'max(int, long int)'

   myByte    = max(5, myParameter.toInt());

                                         ^

C:\Users\Ron\Documents\Arduino\sketch_apr18b\sketch_apr18b.ino:7:41: note: candidates are:

In file included from c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\algorithm:62:0,

                 from C:\Users\Ron\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Arduino.h:257,

                 from sketch\sketch_apr18b.ino.cpp:1:

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4236:5: note: template<class _Tp, class _Compare> _Tp std::max(std::initializer_list<_Tp>, _Compare)

     max(initializer_list<_Tp> __l, _Compare __comp)

     ^

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4236:5: note:   template argument deduction/substitution failed:

C:\Users\Ron\Documents\Arduino\sketch_apr18b\sketch_apr18b.ino:7:41: note:   mismatched types 'std::initializer_list<_Tp>' and 'int'

   myByte    = max(5, myParameter.toInt());

                                         ^

In file included from c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\algorithm:62:0,

                 from C:\Users\Ron\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Arduino.h:257,

                 from sketch\sketch_apr18b.ino.cpp:1:

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4231:5: note: template<class _Tp> _Tp std::max(std::initializer_list<_Tp>)

     max(initializer_list<_Tp> __l)

     ^

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algo.h:4231:5: note:   template argument deduction/substitution failed:

C:\Users\Ron\Documents\Arduino\sketch_apr18b\sketch_apr18b.ino:7:41: note:   mismatched types 'std::initializer_list<_Tp>' and 'int'

   myByte    = max(5, myParameter.toInt());

                                         ^

In file included from c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\algorithm:61:0,

                 from C:\Users\Ron\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Arduino.h:257,

                 from sketch\sketch_apr18b.ino.cpp:1:

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:260:5: note: template<class _Tp, class _Compare> const _Tp& std::max(const _Tp&, const _Tp&, _Compare)

     max(const _Tp& __a, const _Tp& __b, _Compare __comp)

     ^

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:260:5: note:   template argument deduction/substitution failed:

C:\Users\Ron\Documents\Arduino\sketch_apr18b\sketch_apr18b.ino:7:41: note:   deduced conflicting types for parameter 'const _Tp' ('int' and 'long int')

   myByte    = max(5, myParameter.toInt());

                                         ^

In file included from c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\algorithm:61:0,

                 from C:\Users\Ron\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Arduino.h:257,

                 from sketch\sketch_apr18b.ino.cpp:1:

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:216:5: note: template<class _Tp> const _Tp& std::max(const _Tp&, const _Tp&)

     max(const _Tp& __a, const _Tp& __b)

     ^

c:\users\ron\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\xtensa-lx106-elf\include\c++\4.8.2\bits\stl_algobase.h:216:5: note:   template argument deduction/substitution failed:

C:\Users\Ron\Documents\Arduino\sketch_apr18b\sketch_apr18b.ino:7:41: note:   deduced conflicting types for parameter 'const _Tp' ('int' and 'long int')

   myByte    = max(5, myParameter.toInt());

                                         ^

exit status 1
no matching function for call to 'max(int, long int)'

I have another similar statement that uses the “min” function that gives the same error.

I am running Arduino IDE 1.8.9, and since ESP8266 is listed prominently in the “candidates” for the cause of the problem, I will mention that I have installed the library"esp8266 by ESP8266 Community" version 2.5.0.

Finally, I would think that the following statement should work:

myByte  = max(5,  myParameter.toInt(myParameter.substring(pBegin, pParam)));

…but I found that I had to break the statement into two parts, at which time it would compile fine (on the MEGA).

myTempParameter = myParameter.substring(pBegin, pParam);
myByte  = max(5,  myTempParameter.toInt());

This seems like it could be a compiler issue(?) - or, just a dumb programmer.

The problem is that you're passing parameters of two different types to max(). Although that is valid when using the official Arduino cores, it is not when compiling for ESP8266. The solution is to make the two types passed to the function the same. In the case of an integer constant like 5, it defaults to int, but you can use the data type formatters to specify its type:
https://www.arduino.cc/reference/en/language/variables/constants/integerconstants/#_notes_and_warnings

myByte    = max(5L, myParameter.toInt());

In the case of a variable, you can use type casting:
https://www.arduino.cc/reference/en/language/variables/conversion/longcast/

myByte    = max((long)foo, myParameter.toInt());

Here's the definition of max() used when you compile for the Mega 2560:

#define max(a,b) ((a)>(b)?(a):(b))

ESP8266 got rid of that macro and uses std::max instead, which is template-based:
http://www.cplusplus.com/reference/algorithm/max/
The template system allows the use of max() with various parameter types, while requiring that both parameters be of the same type.

The ESP8266 developers' response to all the people who complained that this broke their code was that the broken code was bad because you should not compare different data types and so it wasn't their problem. I feel that it's acceptable to make breaking changes to the API when that has clear benefits and the impacts have been thoroughly considered. However, it's crucial that the change should be clearly documented, which includes a major version bump. The ESP8266 core developers did not bother to do that. The change was made between the 2.3.0 and 2.4.0 releases. The minor version bump indicates that there were only non-breaking API changes. If people had seen that a 3.0.0 version had been released, that would have indicated a breaking API change and they would have been more likely to research what the change was before updating. With a minor version bump, it might be nice to check the changelog to see whether some new useful functionality was added, but you shouldn't need to worry about an update breaking your code.

Thank you for the thorough information and background of the cause. It's very nice to know for future cases that are sure to come up.