This is an excellent question to illustrate the amount of string copying and heap operations (malloc/free) going on when using the Arduino String class.
void loop()
{
Serial.println(foo("def"));
while(1);
}
The compiler will generate loop() something like this:
void loop()
{
// String literal is stored in program memory. Needs to be copied
// to temporary variable.
static const char temp0[4] PROGMEM = "def";
const char temp1[4];
copy_from_program_memory(temp1, temp0);
// The parameter to the call to foo() is actually a temporary String
// variable constructed from the string literal. Storage is allocated
// on the heap and the assigned from the value of the string literal.
String temp2;
temp2.constructor(temp1);
// The return value of the call to foo() is a String that is passed
// to Serial.println(). This is also a temporary String variable.
String temp3;
temp3.constructor(foo(temp2));
Serial.println(temp3);
// The String class destructor has to be called for the temporary
// String variable so that the string values on heap are deallocated.
temp2.destructor();
temp3.destructor();
}
Note that each call to the constructor involves allocating and copying data to the heap.
String foo(String arg1)
{
String test = "abc";
test = test + arg1;
return test;
}
The function foo() needs to copy strings several times to perform the string concatenation. The operator+ will require an intermediate String copy.
Cheers!