#include <stdio.h>
static char _g_testChar[10] = "-GLOBAL";
static int _g_testInt = 1;
static const char *_g_testConstChar = "-CONSTGLOBAL";
static const int _g_testConstInt = 2;
void main(int argc, char **argv)
{
char *testConstChar = "-CONSTCHAR";
char testChar[10] = "-STACKCHAR";
const int testConstInt = 3;
int testInt = 4;
char *cPtr;
int *iPtr;
cPtr = (argc > 1) ?
( (argv[1][0] == 'c') ? testConstChar :
(argv[1][0] == 'C') ? _g_testConstChar :
(argv[1][0] == 'g') ? _g_testChar : testChar )
: testChar;
iPtr = (argc > 2) ?
( (argv[2][0] == 'c') ? &testConstInt :
(argv[2][0] == 'C') ? &_g_testConstInt :
(argv[2][0] == 'g') ? &_g_testInt : &testInt )
: &testInt;
printf(" Char Int\n"
"Constant: %-15p %p\n"
"Stack: %-15p %p\n"
"Const Global: %-15p %p\n"
"Global: %-15p %p\n",
testConstChar, &testConstInt,
testChar, &testInt,
_g_testConstChar, &_g_testConstInt,
_g_testChar, &_g_testInt);
printf("Trying char [%s]...\n", cPtr);
*cPtr = '!';
printf("Trying int [%d]...\n", *iPtr);
*iPtr = 0;
printf("%s\n"
"%d\n",
cPtr, *iPtr);
}
Play with this...it'll show you what your compiler "protects" and what it doesn't. Then look closely at the address table printed and look for the address space of your OS (for Linux it's here). What you'll probably see is that the variables you aren't allowed to change get put into the text segment, which can't be modified during runtime (easily).
On an aside, I have history with this because HP-UX was much more relaxed in this area. When we ported our HP-UX code to Linux we found out the hard way because our programs started crashing. It seemed innocent enough to us to have the essence of this:
void do_something(char *d)
{
char *p;
p = strtok(p, ":");
}
main()
{
char *data = "this:is:some:data";
do_something(data);
}
in the code.... Of course, since "this:is:some:data" is stored in the text segment, Linux crashed with the, not so helpful in this case, "segment violation". It dawned on us that the pointer was always in the 0x08 segment when it crashed, then we looked at the Linux address space and found that we were being bit by the compiler putting the string data in the text segment...always. Even worse, for strings it doesn't matter to the compiler whether the data is const or not. For integers, it seems to use const as a hint to go in the text segment if it's global, however stack constants aren't protected (and I suppose really can't be).
As far as Linux is concerned, it seems any quoted string in a source file is immutable and any static const is immutable. Any non-static const is only immutable if you follow the compiler's warnings if you're assigning a const variable's address to a non-const pointer variable.