Question

This code behaves weird in MS Visual Studio:

char *s = "hello";
s[0] = 'a';
printf(s); 

In release build with optimization turned on it ignores s[0] = 'a' and prints "hello". Without optimization or in debug build it crashes with access violation.
Is this behavior is c++ standard compliant or no? In my opinion, compiler should only allow constant references to string literals, i.e.

const char *s = "hello";

EDIT: I know why it works like this, I do not understand why I am allowed to make non const reference to read only memory.

Was it helpful?

Solution

The reason why this code is allowed in the first place (rather than requiring the declaration to be of type char const*) is backwards compatibility to old C code.

Most modern compilers in strict mode will issue a warning for the above code, though!

OTHER TIPS

No, it's not a bug in the compiler. When you write:

char* s = "hello";

The string constant "hello" will be placed in a read-only section and should generate an exception if you try to modify it. (an OS exception, not a C++ exception).

To make it writable, you have to either use an array:

char s[] = { 'h', 'e', 'l', 'l', 'o', 0 };

or, if you really need a pointer, make it point to an array:

char _s[] = { 'h', 'e', 'l', 'l', 'o', 0 };
char* s = _s;

I can see your point about only allowing const pointers to be initialized with string literals, but I think that would break a lot of existing code.

I think C++ compilers are allowed to allocate string literals in read only memory pages per the standard.

This won't work because *s is pointing to the memory address of a string constant, which you're not allowed to change.

I'm actually a little surprised you don't don't get an access violation when it's compiled with optimizations.

char *s = "foo";

is a tricky pony. It doesn't tell you that this really is a read-only string when in reality it is. This is so, because, you could have your colleague write another string like:

char *t = "foo";

Now, the compiler, at its helpful best will keep only one copy, and changing one would mean a lot of work only to keep you and your friend happy. So, it doesn't try to do that. This is something you should find in the standard. Guess what, what you're doing invokes UB.

That said, if you were to have your way, it would break a lot of legacy code which the poor guys at the Standards Committee couldn't afford. So, there you are.

Remember the const we are guilty of carefree usage wasn't born in a day. Bjarne did a lot of soul-searching and so did a lot of others whether to put it in or not. In fact, he had this excellent idea of having read-only and write-only variables ... but I'll save that story for another day.

And finally, there is our good friend C, who we need to take care of. So ...

As the others said, you can't modify a string literal. I also wonder why you don't get a compiler warning in your code. The compiler can for sure figure out that you're trying to write to read only memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top