ArduinoCore-API icon indicating copy to clipboard operation
ArduinoCore-API copied to clipboard

serial.write(byte)0)

Open ghost opened this issue 8 years ago • 10 comments

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

ghost avatar Mar 22 '17 12:03 ghost

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!

facchinm avatar Mar 22 '17 15:03 facchinm

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 avatar Mar 28 '17 10:03 descampsa

@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)

facchinm avatar Mar 28 '17 11:03 facchinm

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).

descampsa avatar Mar 28 '17 11:03 descampsa

Ah, it's in the hardware serial code, sorry, my bad :smile:

facchinm avatar Mar 28 '17 12:03 facchinm

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?)

descampsa avatar Mar 29 '17 15:03 descampsa

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).

cousteaulecommandant avatar Apr 11 '17 18:04 cousteaulecommandant

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.

descampsa avatar Apr 11 '17 20:04 descampsa

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.

descampsa avatar Apr 11 '17 20:04 descampsa

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.

PaulStoffregen avatar Apr 12 '17 11:04 PaulStoffregen