Home > Enterprise >  Is it safe returning Arduino String from a C function?
Is it safe returning Arduino String from a C function?

Time:11-13

In software provided for multiple system on a chip microcontrollers I discovered this piece of code

String getMacAddress() {
  uint8_t baseMac[6];
  char baseMacChr[13] = {0};
#  if defined(ESP8266)
  WiFi.macAddress(baseMac);
  sprintf(baseMacChr, "XXXXXX", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
#  elif defined(ESP32)
  esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
  sprintf(baseMacChr, "XXXXXX", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
#  else
  sprintf(baseMacChr, "XXXXXX", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#  endif
  return String(baseMacChr);
}

Where String is provided by Arduino context. So on those microcontroller is this piece of code safe?

I know that there is a problem with the scope/longevity of the returned variable (well explained here: Returning a C string from a function ) which most people get around with the std::string but I don't have any experience in the context of microcontrollers, and since I've seen it used a lot, I've come up with this question.

I haven't found any documentation about it, every bit of extra information is welcome.

CodePudding user response:

The String class in arduino does not store a pointer to a character but copies it into its internal memory.

The copy constructor takes care of the rest when returning String from a function.

So yes, it's safe

CodePudding user response:

Is it safe returning Arduino String

Yes. String manages it's memory.

from a C function?

Well, it's not a "C function", it's a normal function in C .

which most people get around with the std::string but I don't have any experience in the context of microcontrollers

It does not differ that much, and you can also use std::string on esp.

String and other similar interfaces from Arduino are there to save memory (use realloc, instead of delete new on resize) and to interface with Arduino specific stuff easier (constructor with __FlashStringHelper). It's meant to "mimic" std::string with some Arduino or embedded specific behavior.

CodePudding user response:

Looks fine to me since you are allocating the strings with automatic storage duration in the caller to the function.

Check they are of sufficient size though - you need to consult the function documentation for that.

With return String(baseMacChr);, baseMacChr does not go out of scope conceptually until the closing } of the function getMacAddress, so that too is safe.

If you can use std::string rather than String then it would be even better. Every C programmer knows exactly what the former is. Using String (whatever that is) can only add to confusion.

  • Related