Why does snprintf gives me an invalid conversion warning for my code.
As you will notice, I'm not using String, because it uses dynamic memory allocation.
src\Thermometre.cpp: In member function 'virtual const char* Thermometre::GetCSV()':
src\Thermometre.cpp:137:46: warning: invalid conversion from 'const char*' to 'char*' [-fpermissive]
snprintf (CSV, sizeof(CSV), "%s;", str_temp); // TODO Fix invalid conversion
^
In file included from C:\.platformio\packages\framework-arduino-avr\cores\arduino/Print.h:24:0,
from C:\.platformio\packages\framework-arduino-avr\cores\arduino/Stream.h:26,
from C:\.platformio\packages\framework-arduino-avr\cores\arduino/HardwareSerial.h:29,
from C:\.platformio\packages\framework-arduino-avr\cores\arduino/Arduino.h:233,
from src\Thermometre.cpp:1:
c:\.platformio\packages\toolchain-atmelavr\avr\include\stdio.h:687:12: note: initializing argument 1 of 'int snprintf(char*, size_t, const char*, ...)'
extern int snprintf(char *__s, size_t __n, const char *__fmt, ...);
^~~~~~~~
'const' is your promise to the compiler that you won't attempt to change the values in that array. You're breaking that promise with the snprintf() call.
BTW, you're also breaking it with the memset(). But, the cast is keeping the compiler quiet about it.
Nice use of snprintf. Where you going to check the for failure there or are you just happy to have an empty CSV returned if snprintf fails. No need for the memset CSV, unless you code somewhere else does not just treat it as a null terminated string.
Also while snprintf is 'safe' against buffer overflows, dtostrf is not. The 'width' 4 is the minimum width and does not prevent a large lastReading from overflowing str_temp.
If you really want bullet proof code, without using Strings, you could add
As an alternative to Strings take a look at my SafeString library which does not use dynamic memory, just char[ ]s but protects you against buffer overflows, missing '\0' etc and outputs detailed error messages if it finds any, while provide the similar high level text manipulation as Strings. Plus extras
In particular, the SafeString print(lastReading, 2, 8) will format lastReading into the char[ ] held in SafeString and pad to 8 char wide while protecting against buffer overflow. You can also justify left or right and force a + sign if you want using extra args options.
Edit -- SafeString lets you 'wrap' a class static char[ ] so you can update it safely using the SafeString methods.
Is a signal to the compiler that the contents of this char* are not expected to be changed by the method and to complain if the code tries to update anything pointed to by that char*.
So const char* and char* are actually the same address, only the compilation checks are changed.
no, it is just a variable, you can point it to a different memory address to different char array. const there means content of the memory should not be changed but not the address pointer is holding. you can make pointer constant too then it will always be pointing to the same address.