
#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) There is a macro named "F" in the standard include file Wstring.h: class _FlashStringHelper there is a special trick used to make keeping them out of SRAM easier. Because they are often used for text output to Serial, LCD, Ethernet, WiFi, etc. They are treated like initialized read-only variables and their space in SRAM is initialized by copying the data from FLASH. String literals are a special case of initialized variables. It is up to you to add the special function calls to fetch data from FLASH whenever you want to fetch data from that variable. It won't remember that your variable is in FLASH and if you try to use it like you would any other variable it will use that FLASH address to fetch data from SRAM and get the wrong data. Unfortunately, the compiler will only keep track of the address of the variable, not which address space it is in. (Note: The special instructions for writing into FLASH can only be executed from the BOOTLOADER area of the FLASH memory. For larger initialized read-only variables, such as lookup tables, it is good to tell the compiler to keep the data in FLASH. This is great for initialized variables that will be modified by the sketch but for constant (read-only) variables it is a waste of precious SRAM space.

Any initialized variables will be initialized by copying the data from FLASH to the variable's location in SRAM before the sketch starts. You have to use special machine instructions for reading (or writing) FLASH or reading or writing EEPROM.

Instructions are fetched from FLASH (a.k.a. On the AVR processor the SRAM, FLASH, and EEPROM are in separate address spaces.
