serial.write(byte)0)
the programmcode 👍 serial.write(0); will work with arduino uno / mega
but with : arduino 101 arduino MO chipKIT uC32
I get an compiler error 👍
test_serial:31: error: call of overloaded 'write(int)' is ambiguous
Serial.write(0);
use :Arduino 1.8.1 win 7
In Serial.write(0); , the 0 could be interpreted as a number or as char* ( (void*)NULL in fact). The fact that AVR is not exposing this bug is quite bugging and needs some further investigation :slightly_smiling_face:
Thanks for reporting!
In AVR, there is a write(int) overloaded method, that match exactly with write(0), so the compiler doesn't complain. On the other side, 101 for example has only a write(uint8_t) method, so the compiler doesn't know if he should use that, or write(const char*), because both require a type conversion.
I am not so sure it is a good idea to hide the fact that write takes only raw bytes by overloading it in the AVR libraries, but i guess that it was done to keep people from complaining about the ambiguous overload ;-)
@descampsa where did you find the write(int) overload?
It looks more complicated than that :smile: On any core, write(1) just works, while the const char* is evaluated as ambiguous only for 0 (which makes sense, since any non-zero number is hardly a pointer unless you cast it explicitly)
It is here : https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/HardwareSerial.h#L133
There is also the c++ quirk that only 0 is implicitly convertible to a pointer, yes, but that's true for all platforms (unless broken compiler).
Ah, it's in the hardware serial code, sorry, my bad :smile:
A possible solution to this problem would be to declare the write(const char*) as a template in Print, and implement only the const char* version, like that (untested) :
template<class T>
size_t write(const T *str);
template<>
size_t write<const char>(const char *str) {
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
When write(0) is called, the compiler will first look at the non-template functions, and call the uint8_t version (same for write(NULL), but who does that?)
Or just do in SAM what is done in AVR and add the write(int) et al methods to HardwareSerial.h.
BTW, a workaround to this particular problem is to do Serial.write(byte(0)) (which is also more elegant IMO).
Or just do in SAM what is done in AVR and add the write(int) et al methods to HardwareSerial.h.
Then you have to do it in SoftwareSerial also (and other Print derived classes, if any), for consistency. It could be in Print, but then i guess that the compiler won't honour the inline (to be checked), and that we don't want another overhead on such a low level function.
BTW, a workaround to this particular problem is to do Serial.write(byte(0)) (which is also more elegant IMO).
That's of course the simplest solution, then the write overloads should be suppressed from HardwareSerial for consistency.
Or just do in SAM what is done in AVR and add the write(int) et al methods to HardwareSerial.h.
Then you have to do it in SoftwareSerial also (and other Print derived classes, if any), for consistency. It could be in Print, but then i guess that the compiler won't inline the function (to be checked), and that we don't want another overhead on such a low level function.
BTW, a workaround to this particular problem is to do Serial.write(byte(0)) (which is also more elegant IMO).
That's of course the simplest solution, then the write overloads should be suppressed from HardwareSerial for consistency.
Then you have to do it in SoftwareSerial also (and other Print derived classes, if any), for consistency.
Then do it also in SoftwareSerial and other Print derived classes, for consistency.