You’ve conflated a couple of different things into ‘static memory’ that it’s worth separating:
Static Memory — Variables declared at file scope have their memory allocated at compile time. At the end of linking, the executable includes a memory map saying “we have 50kB of code and 1kB of data”. When that program is then executed, the program loader will then create 50kB of space and put the program code in it, and another 1kB of space that can be used for read write data. The C runtime (yes, there is one) will then execute at startup (before main()) and initialise that 1Kb of space with the correct data, which will either be 0, or a specific value that it copies from in the middle of the program code. Note that this is all read/write data, not constants etc.
Note that there is a runtime cost — it just happens (very quickly) once at startup. And while you’re right that the initialisation data lives in the program code, the actual memory you are using is separate and allocated by the program loader.
Constant memory — If you static data that the compiler thinks is constant at runtime (e.g. because it’s not ‘mut’ or in C because you’ve put ‘const’), then it goes in another section (actually pretty much the same section as the code). An example would be a string literal in C (string literals are always constant in C):
This line will cause the compiler to put 6 bytes in const memory containing the 5 characters and then a NULL termination. Then when the line of code runs, the argument to printf will be the pointer to that location in constant memory.
On a PC, this memory segment with the const data in will probably have the same permissions as code — you can read and execute it, but not write to it. If you manage to work around the compiler and write to the memory where the const data is, your program will crash with a ‘segfault’ — i.e. you’ve done something illegal for that memory segment. The static data above goes in a segment with different permissions — read and write, but not execute.
[sidenote — the segment permissions are largely for security. It makes an exploit writers job much easier if he can write some arbitrary code into your memory e.g. because it’s the data in a network packet, and then somehow trick your program into executing it. If there is no section that you can both write to and execute then that isn’t possible]
For more details see this article on sections in a Linux binary:
January 3, 2013 This article was contributed by Daniel Pierre Bovet A section is an area in an object file that…lwn.net
Note that the static data is actually 2 sections, that separate the data that is initialised to zero, and that with specific initialisation. These sections are called .bss and .data respectively. The const data is .rodata (for read-only data), and the code is called .text.