This is kind of interesting (to me anyway). I’ve seen recommended multiple times on this forum to use this construct to place character strings in Flash:
const char * const dog1 PROGMEM = "Hello World";
Well, on an Uno-compatible board anyway, it doesn’t do that:
const char * const dog1 PROGMEM = "Hello World";
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println(dog1);
memcpy((uint8_t *)dog1, (const uint8_t *)"Goodbye", 7);
Serial.println(dog1);
}
void loop() {
}
Producing Serial Monitor output:
Hello World
Goodbye World
Besides being able to programmatically change the string at runtime, another clue is that the ‘Serial.println(dog1);’ actually works. It shouldn’t since dog1 is a ‘char *’, so the overloaded version of ‘println()’ that pulls strings from Flash isn’t being compiled. That requires type ‘__FlashStringHelper *’.
Something I don’t understand is that if I increase the size of the string by 10 bytes:
const char * const dog1 PROGMEM = " Hello World";
then, the compiler reports a 10 byte increase in BOTH RAM and Flash usage.
Finally, I think this definitely puts the string in Flash:
const char dog[] PROGMEM = "Hello World";
__FlashStringHelper *dog2 = (__FlashStringHelper *) dog;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println(dog2);
}
void loop() {
}
Changing the string length only changes the reported Flash usage.
So, no question here. Just thought others might also find it interesting.