Edit: Adding some clarifications.
All this complexity about flash vs. RAM storage comes from the fact that the AVR uses a Harvard architecture, where RAM and flash are in different address spaces, accessed through different memory buses using different machine instructions. Unlike C, the C++ language has no notion of address spaces, and the compiler simply assumes that any pointer to function holds a flash address, whereas any pointer to data holds a RAM address.
Per the rules of the language, a string literal has the type
const char *, and a function that should be able to accept a string
literal should take a const char * parameter. Since these are pointers
to data, when you dereference them the compiler emits the machine
instructions that are appropriate for reading RAM. This is why the
compiler puts all string literals in the .data section of the flash: at
program startup, the C runtime copies them to the .data section of the
RAM, making them accessible to those machine instructions.
The current solution to avoid this useless copy involves a bunch of
preprocessor macros like F(), PSTR(), PROGMEM,
pgm_read_byte()... that expand to compiler extensions or inline
assembly. These allow you to pass around the flash addresses of string
literals disguised as regular data pointers. These pointers should never
be dereferenced with the regular operators of the language (* and
[]), but only through the pgm_read_*() macros. And they should only
be given to functions that do expect these kind of pointers, like
sprintf_P() or Print::println(const __FlashStringHelper *), which is
the println() that gets invoked when using the F() macro.
Is there any way to put the literal in stack
Yes, there is, but it has to be done explicitly:
PROGMEM const char greeting[] = "Hello, World!";
void say_hello() {
char stack_copy[strlen_P(greeting)+1];
strcpy_P(stack_copy, greeting);
Serial.println(stack_copy);
}
As you have already noticed, it is preferable to not put the strings in
RAM at all, and instead use functions like sprintf_P that expect
flash-based strings. However, if you need to use a library function that
expects a RAM-based string, you can use this trick to avoid permanently
committing it to RAM.