Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal to modify an object created with new through a const pointer?

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.

like image 932
Luchian Grigore Avatar asked Apr 01 '14 23:04

Luchian Grigore


People also ask

Can you modify a const pointer?

A const pointer to a const value can not have its address changed, nor can the value it is pointing to be changed through the pointer. It can only be dereferenced to get the value it is pointing at.

Can const pointer be deleted?

E2158 Operand of 'delete' must be non-const pointer (C++)It is also illegal to delete a pointer to a constant.


2 Answers

new obviously doesn't create a const object (I hope).

If you ask new to create a const object, you get a const object.

there's no reason you can't legally const_cast the constness away and actually modify the object.

There is. The reason is that the language specification calls that out explicitly as undefined behaviour. So, in a way, you can, but that means pretty much nothing.

I don't know what you expected from this, but if you thought the issue was one of allocating in readonly memory or not, that's far from the point. That doesn't matter. A compiler can assume such an object can't change and optimise accordingly and you end up with unexpected results.

like image 79
R. Martinho Fernandes Avatar answered Oct 20 '22 06:10

R. Martinho Fernandes


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 constness and mutating the object would still be an undefined operation.

constness 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.

like image 20
Lightness Races in Orbit Avatar answered Oct 20 '22 05:10

Lightness Races in Orbit