(S)tring - Hey Mr Compiler, keep your greedy hands off my precious memory!!!

After much frustration trying to reduce my RAM usage I realized that all my literal strings (ie Serial.println("Big long static text goes in here..")) were occupying space in program memory AND also in RAM.

I read some excellent articles on liuzengqiang 's website (liudr.wordpress.com) and learned to use PROGMEM to force the literal string data to only reside in program memory.

But I wonder, what the heck is the purpose of this "feature" in the compiler? It sees that its a literal that wont ever change, why doesn't it automatically do the equivalent of me going through and adding PROGMEM in front of all my strings?

Is this is a "bug" or limitation, or is there some legitimate situation where you would actually want static data stored in both places?

(Of course, most articles written about the String datatype vehemently say DONT USE THEM and use character arrays instead, maybe i should listen... but the capital 'S' Strings are just so darn convenient sometimes....)

If it's a static, "literal string", use the F() macro. It's a lot easier than PROGMEM. The compiler has no way of automatically dealing with PROGMEM in any reasonable manner.

Regards,
Ray L.

muzzlevelocity:
vehemently say DONT USE THEM and use character arrays instead, maybe i should listen.

Indeed you should listen.....

muzzlevelocity:
But I wonder, what the heck is the purpose of this "feature" in the compiler? It sees that its a literal that wont ever change, why doesn't it automatically do the equivalent of me going through and adding PROGMEM in front of all my strings?

There still may be some instances where storing static strings in SRAM is more optimal. Flash memory has slower access time and a finite number of write/erase cycles. It's better to let the programmer decide which way suits best for their project.

Most likely the easiest thing to do for you is to use F()

Serial.println(F("This is stored in Flash"));

However if your string output is simply for debugging, another consideration is to use a compile time macro to remove all calls to Serial.println when you are no longer troubleshooting/testing your system.

jeffez:
Flash memory has slower access time

ah, that makes sense. Thank you.

(and yes I was using F(), not actually "PROGMEM". my understanding was that F() was using PROGMEM under the hood, but thats neither here nor there...)

Also, program memory resides in a separate address space and requires a different instruction to access - so they're not interchangable (this is why there are two versions of most string handling functions). The print() methods, F() macro, and __FlashStringHelper hide that complexity when you're just using it to store string literals.

Well, the string has to be stored in flash to be present at all, and it has to be stored in RAM so that C can access it by pointers and such. As DrAzzy said, flash memory on the AVR is in a separate address space from normal data, and it take user-provided code to access it, rather the the intrinsic C++ operators. (Fortunately, the Arduino IDE provides that code for you!)