Fix “ISO C++ says that these are ambiguous” (Wire.requestFrom)
A warning, not an error: Wire.requestFrom() got a uint8_t and an int, matching two overloads. Cast both arguments to the same type to silence it.
Community draft — report a mistake
What you see
MPU6050_raw.ino: In function 'void setup()':
MPU6050_raw.ino:5:27: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
Wire.requestFrom(addr, 6);
^
In file included from MPU6050_raw.ino:1:0:
Wire\src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
uint8_t requestFrom(int, int);
^~~~~~~~~~~
Wire\src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
uint8_t requestFrom(uint8_t, uint8_t);
^~~~~~~~~~~
Sketch uses 2312 bytes (7%) of program storage space. Maximum is 32256 bytes.MPU6050_raw.ino: In function 'void setup()':
MPU6050_raw.ino:5:27: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
Wire.requestFrom(addr, 6);
^
In file included from MPU6050_raw.ino:1:0:
Wire\src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
uint8_t requestFrom(int, int);
^~~~~~~~~~~
Wire\src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
uint8_t requestFrom(uint8_t, uint8_t);
^~~~~~~~~~~
Sketch uses 2312 bytes (7%) of program storage space. Maximum is 32256 bytes.
This message looks alarming because of its length, but it is only a warning. Two versions of Wire.requestFrom() fit your call equally badly, GCC picked one, and it is telling you the standard says it shouldn’t have to.
const uint8_t MPU = 0x68;
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU, (uint8_t)14, (uint8_t)true); // all uint8_t: no warningQuick fix — try in order
- 1
Notice it still compiled
It is a
warning:and the “Sketch uses … bytes” line follows. The program works; the warning only appears when compiler warnings are turned on in Preferences. - 2
Make both arguments the same type
Wire.requestFrom(addr, (uint8_t)6);whenaddris auint8_t, or declare the address asint. Then only one overload matches exactly. - 3
Same fix for the 3-argument form
Wire.requestFrom((uint8_t)MPU_ADDR, (uint8_t)14, (uint8_t)true);is the version most MPU6050 examples need. - 4
Real error variant: “call of overloaded … is ambiguous”
When no candidate is better at all, it becomes an
error:, e.g.call of overloaded 'abs(unsigned int)' is ambiguous. Cast the argument to the type you mean (abs((int)x)).
Why it happens
What is an overload?
Several functions with the same name but different parameter types. requestFrom exists for (uint8_t, uint8_t) and for (int, int). A uint8_t plus a plain number literal (an int) matches each one half-way.
Why does the compiler pick one anyway?
GCC applies a tie-break rule the C++ standard doesn’t require, chooses candidate 1, and warns you that a stricter compiler could refuse.
Do I need to fix it?
Not urgently, but a clean build makes real warnings easier to spot. The cast is one word.
Board-specific notes
ESP32: The ESP32 Wire library uses different parameter types (uint16_t, size_t) and doesn’t warn for this call.
Parts: MPU6050 — address 0x68, register map notes.
Did this fix it?
Thanks — that helps us keep this page right.