Is it legal to modify an object created with new through a const pointer?
c++, constants, language-lawyer
Solution
`const` is part of the type. It doesn't matter whether you allocate your object with dynamic, static or automatic storage duration. It's still `const`. Casting away that `const`ness and mutating the object would still be an undefined operation.
`const`ness is an abstraction that the type system gives us to implement safety around non-mutable objects; it does so in large part to aid us in interaction with read-only memory, but that does not mean that its semantics are restricted to such memory. Indeed, C++ doesn't even know what is and isn't read-only memory.
As well as this being derivable from all the usual rules, with no exception [lol] made for dynamically-allocated objects, the standards mention this explicitly (albeit in a note):
`[C++03: 5.3.4/1]:` The new-expression attempts to create an object of the type-id (8.1) or new-type-id to which it is applied. The type of that object is the allocated type. This type shall be a complete object type, but not an abstract class type or array thereof (1.8, 3.9, 10.4). [Note: because references are not objects, references cannot be created by new-expressions. ] [Note: the type-id may be a cv-qualified type, in which case the object created by the new-expression has a cv-qualified type. ] [..]
`[C++11: 5.3.4/1]:` The new-expression attempts to create an object of the type-id (8.1) or new-type-id to which it is applied. The type of that object is the allocated type. This type shall be a complete object type, but not an abstract class type or array thereof (1.8, 3.9, 10.4). It is implementation-defined whether over-aligned types are supported (3.11). [ Note: because references are not objects, references cannot be created by new-expressions. —end note ] [ Note: the type-id may be a cv-qualified type, in which case the object created by the new-expression has a cv-qualified type. —end note ] [..]
There's also a usage example given in `[C++11: 7.1.6.1/4]`.
Not sure what else you expected. I can't say I've ever done this myself, but I don't see any particular reason not to. There's probably some tech sociologist who can tell you statistics on how rarely we dynamically allocate something only to treat it as non-mutable.
Problem
So this answer made me think about the scenario where you assign the result of `new` to a pointer to a `const`. AFAIK, there's no reason you can't legally `const_cast` the constness away and actually modify the object in this situation: ``` struct X{int x;}; //.... const X* x = new X; const_cast<X*>(x)->x = 0; // okay ``` But then I thought - what if you actually want `new` to create a `const` object. So I tried ``` struct X{}; //.... const X* x = new const X; ``` and it compiled!!! Is this a GCC extension or is it standard behavior? I have never seen this in practice. If it's standard, I'll start using it whenever possible.