I’m new to Particle and found myself using c_str() without thinking about whether it was supported or not. As I was studying the firmware reference found here:
I was surprised not to see c_str() included in the APIs. My question … is this a deliberate choice not to document it? Should I not use the c_str() function if I want to ensure portability and long-term support of my code?
c_str() is also a feature used on Arduinos and hence Particle won’t let it die - but I personally prefer the type cast version (const char*)someString as it can be used with both C-strings and String objects.
So refactoring a String into a C-string would not break existing code.
I was trying to figure out whether I should be using a string (const char *) or String in publish() and subscribe(). The compiler seemed not to care, but I was trying to pin this down…
In the reference docs, publish() mentions both explicitly: subscribe() just gives an example with a const char *. In the .h files, all I could find was const char *. I finally stumbled across this discussion, as well as evidence that it actually got implemented.
If not there already, this seems important enough to highlight in the docs, perhaps in the preamble to String – merely a note that whenever a const char * is required a String will work (unless I’ve got this totally wrong, in which case nvm😀)
I won’t stop advocating against the use of String due to its potential risk of causing heap fragmentation which may - over time - cause unexpected, hard to debug behaviour.
So whenever you can go with char*, const char*, char[] and const char[].
Whenever you need a const c-string, there are two ways to get one from a String object:
operator const char *, which is what you get when you cast a String as a const char *
The method c_str(), which also returns a const char *.
For functions that take a const char * parameter, you don’t even need the cast, because the compiler will automatically use operator const char *.
The place where you get into trouble is when you pass a String to variable arguments, such as Log.info and sprintf. The compiler doesn’t know what type you want, so you need to explicitly cast as (const char *) or use the c_str() method.