What guarantees does D 'const' provide, compared to C++?

Chris Cain clcain at uncg.edu
Thu Aug 16 19:46:34 PDT 2012


On Friday, 17 August 2012 at 02:02:56 UTC, Jonathan M Davis wrote:
>
> How is it a bug? The variable that you're altering is not part 
> of the object.
> That's part of why having pure with const in so valuable. It 
> prevents stuff
> like what you're doing here.
>
> - Jonathan M Davis

Notice that I'm making an immutable(S) in that example. It should 
then transitively mean that the data pointed to will be immutable 
as well. The reason this is a bug is because the constructor is 
currently set up to have the thing you're working with be mutable 
while you're still constructing it (otherwise, you couldn't even 
initialize any of the fields). However, this allows invalid code.

Here's a bit simplified version with some extra output:

int gCount;

struct S {
     int* it;
     this(int i) {
         writeln("--- constructor begin ---");
         gCount = i;
         it = &gCount; // Should be compile error
                       //when constructing immutable(S)
         writeln(typeof(it).stringof, " it = ", *it);
         writeln("^^ Notice, typeof(it) is always mutable!");
         writeln("--- constructor end ---");
     }
     ref const(int*) getItem() const {
         ++gCount;
         return it;
     }
}

import std.stdio;

void main() {
     immutable(S) s = immutable(S)(0);
     auto it = s.getItem();
     writeln(typeof(s.it).stringof, " s.it = ", *s.it);
     writeln(typeof(it).stringof, " it = ", *it);
     writeln(typeof(gCount).stringof, " gCount = ", gCount);
     s.getItem();
     writeln(typeof(s.it).stringof, " s.it = ", *s.it);
     writeln(typeof(it).stringof, " it = ", *it);
     writeln(typeof(gCount).stringof, " gCount = ", gCount);
}



I'm almost sure it's been reported before because I've seen talk 
about this particular issue in the past.

If you run this with optimizations off and on, it shows off the 
type of optimizations that can be made when something is 
immutable. For instance, with optimizations off you get:
...
immutable(int*) s.it = 1
const(int*) it = 1
int gCount = 1
immutable(int*) s.it = 2
const(int*) it = 2
int gCount = 2

and on:
...
immutable(int*) s.it = 1
const(int*) it = 1
int gCount = 1
immutable(int*) s.it = 1
const(int*) it = 2
int gCount = 2

As you can see, the optimization is that it doesn't even check 
s.it's memory location, it just puts the previous value in place.

But yeah, it's a bug that this code is allowed.


More information about the Digitalmars-d mailing list