2

I'm using the SPISlave library, and I have the following code snippet:

String arg;

SPISlave.onData([arg](uint8_t *data, size_t len) {
  data[len] = 0;
  arg += String((char *)data);
  // ...
}

The compiler doesn't like my string concatenation, though:

/home/lars/sketch_apr01a/sketch_apr01a.ino: In lambda function: sketch_apr01a:65:12: error: passing 'const String' as 'this' argument of 'String& String::operator+=(const String&)' discards qualifiers [-fpermissive] arg += String((char *)data);

I've tried other versions as well, with similar results:

  • arg.concat((char *)data)
  • arg = arg + String((char *)data)
  • arg += String((const char *)data)

So how exactly do I write this unusual operation?

1
  • Funny, on avr-g++ it's fine (with warnings about store duration). Anyway, you are capturing the arg variable by value, so it won't affect variable outside lambda function.
    – KIIV
    Commented Aug 26, 2019 at 19:01

3 Answers 3

3

Your lambda is capturing arg by copy, which is most certainly not what you want. And since it doesn't have the mutable qualifier, the captured parameters are not modifiable. Hence the compiler error.

You could get rid of the error by qualifying the capture as mutable, but you would then be modifying the captured copy of arg, not the original one. The correct solution would be to capture the String by reference instead of capturing by copy. See Lambda expressions.

But then, I concur with Michel Keijzers that avoiding Strings altogether is a better option.

2
  • Makes perfect sense, thanks!
    – larsb
    Commented Aug 26, 2019 at 19:32
  • Thanks for the insight and correct answer too (upvoted) Commented Aug 26, 2019 at 22:13
2

Actually for such string concatenation (which is in a function that may be called a lot), this could result in memory fragmentation, an on most Arduinos the memory will be soon too scattered that no useful memory is left.

Instead, it's better to create beforehand a buffer with the maximum size of the string you want to handle, like:

static const int MAX_BUFFER_LENGTH = 256;

char buffer[MAX_BUFFER_LENGTH];

And use the function strcat or strncat for concatenating two strings; there are generic C functions.

2
  • Fair enough, and good advice in general. But I'd still like to know the answer to my question. :-)
    – larsb
    Commented Aug 26, 2019 at 18:50
  • I wonder what error you get when using concat (cannot be a String passing operation error). Maybe some casting to const. Commented Aug 26, 2019 at 18:53
1
#include <stdio.h>

static const int MAX_BUFFER_LENGTH = 32;
char buffer[MAX_BUFFER_LENGTH];

sprintf(buffer, "%s%s", string1, string2);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.