Fixing "call of overloaded ... is ambiguous" in Arduino
Beginner
Or see every lesson.
- 505parts on the bench
- 45boards running now
- 1.00xreal time, on every board
call of overloaded 'show(double)' is ambiguous means there is more than one function with that name, each taking a different type, and the value you passed fits two or more of them equally well, so the compiler will not guess. The type in the brackets is what you passed. The notes under the error list the candidates it could not choose between. The fix is to make the value the exact type of one of them, with a cast such as (int) or byte(0), or a suffix such as 2.5f.
In Arduino sketches it comes from four places: lcd.write(0) for a custom character, abs() on an unsigned value on the ESP32, Serial.print of a long long on an Uno, and functions of your own with the same name. Mokxi compiles with clang, which says call to 'show' is ambiguous. The circuit above shows a message and a heart on an LCD; its sketch has a show(int n), and adding a second show breaks it.
Your own functions with one name
C++ lets two functions share a name if they take different types. Calling one with a type that is neither forces a conversion, and if two conversions are equally good the call is ambiguous. With void show(int value) and void show(float value), show(2.5) gave GCC 13’s call of overloaded 'show(double)' is ambiguous, with the notes candidate: 'void show(int)' and candidate: 'void show(float)'. 2.5 is a double, and double to int and double to float count the same. show(100000L), a long, gave call of overloaded 'show(long int)' is ambiguous.
Clang said call to 'show' is ambiguous, with a candidate function note at each one, and Mokxi’s build tab says: "show has more than one version, and the values given fit two of them equally well. Make a value's kind plain: (long)value, or 1.0 rather than 1 for a decimal." The demo’s break is this case: the gift sketch’s show(int n) and a new show(float level), called with 0.5.
Make the value exact: show(2.5f) picks the float one and printed 2.50, and show((int)2.5) the int one. Or add a version for the type you pass: with a show(long value) as well, show(100000L) printed 100000.
void show(int value) {
Serial.println(value);
}
void show(long value) {
Serial.println(value);
}
void show(float value) {
Serial.println(value);
}
void setup() {
Serial.begin(9600);
show(2.5f);
show(100000L);
}
void loop() {
}Open this sketch in the editorThe code alone: the editor places the board and the parts it can read from the sketch.
"write(int)": lcd.write(0) for a custom character
An LCD stores up to eight characters you draw yourself, in slots 0 to 7, and lcd.write(n) shows one. Arduino’s LiquidCrystal library has write(uint8_t) for a character and write(const char *) for text, and a plain 0 fits both: it is an int that can become a byte, and it is also the null pointer. GCC 13, on a copy of those two functions, said call of overloaded 'write(int)' is ambiguous. Slots 1 to 7 are fine, because only 0 can be a pointer.
The fix is the one in the library’s own CustomCharacter example: lcd.write(byte(0));. The gift sketch above calls lcd.write(0) for its heart and builds in Mokxi, because Mokxi’s LCD libraries add a write(int) that takes the slot number. Write byte(0) anyway, and the sketch builds in the Arduino IDE as well.
"abs(long unsigned int)": abs() on an unsigned value
On the Uno, abs() is a macro in the Arduino core, so it never gives this error. The ESP32 core takes abs() from the C++ library instead, with using std::abs;, which has versions for int, long, long long and the floating point types, and none for unsigned values. abs(millis() - start) passes an unsigned long and GCC 13 said call of overloaded 'abs(long unsigned int&)' is ambiguous, and abs(a - b) with two unsigned ints call of overloaded 'abs(unsigned int)' is ambiguous.
The error is doing you a favor, because an unsigned value is never negative: 3 minus 5 wraps around to a huge number. Mokxi’s abs() takes any number, so the line builds with a warning, taking the absolute value of unsigned type 'unsigned int' has no effect, and on the Uno abs(a - b) with a at 3 and b at 5 printed 65534. Convert before you subtract, abs((int)a - (int)b), which printed 2. For times, millis() - start is already the right way around and needs no abs() at all.
"print(long long int&)": a 64-bit number on an Uno
The Uno’s Serial.print has versions for char, int, long, their unsigned partners and double, and none for long long, the 64-bit type. Every one of them is an equally good conversion, so Serial.print(big) with long long big gave GCC 13’s call of overloaded 'print(long long int&)' is ambiguous, listing seven candidates, on a copy of the AVR core’s list. Mokxi’s Print has a long long version, so the same line built here and printed 1234567890123.
In the Arduino IDE on an Uno, print it as a long if the value fits, Serial.print((long)big), or split it into two parts. A long double, rarer still, is ambiguous in Mokxi too: clang said call to member function 'println' is ambiguous. Use a double.
Open this circuit in the editor. Arduino Uno: a gift message on an LCD, wired as it runs at the top of this page. Change a part or a value and run it again.
Open the circuitQuestions
What does "call of overloaded ... is ambiguous" mean?
There are several functions with that name, and the value you passed fits two or more of them equally well. Cast the value to the exact type of the one you want, or add a version for its type.
How do I fix "call of overloaded 'write(int)' is ambiguous" on an LCD?
Write lcd.write(byte(0)) for custom character 0. A bare 0 can be a byte or a null pointer, and the library has a write for each.
Why is abs() ambiguous on the ESP32 but not on the Uno?
The Uno core makes abs() a macro, and the ESP32 core uses the C++ library’s abs(), which has no unsigned version. Convert the values to int or long before you subtract.
What does Mokxi say instead?
Mokxi compiles with clang, which says call to 'show' is ambiguous, or call to member function 'println' is ambiguous for a class’s function, with a note at each candidate.
Keep going
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.