www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - If I understand const right...

reply cy <dlang verge.info.tm> writes:
a = a + 1

a is const, a + 1 is const, yet a can't be assigned to a + 1. And 
I think the reason is like...

const(int) a = 23;
while(something()) {
   a = a + 1;
}

in the first iteration, a is set to 23, and the value of "a + 1" 
is 24, but where is the computer gonna store that 24? It can't 
store it where 23 is, because that's constant data. In a register 
variable? What about the next iteration? A runtime queue of 
previously calculated consts that builds up with each iteration?

...not gonna happen. So since there's nowhere to store that 24 
(without some non-const variable to store it in), you can't point 
"a" at the new address, even if 24 itself would fit inside 
another constant bit of memory just fine.

I'm actually used to the runtime queue thing, from scheme and the 
like. "a = a + 1" allocates a new bit of memory, made immutable 
and never changed from then on, storing "a + 1" in it and 
pointing a at it. And if "a + 1" has already been calculated, it 
finds that old value and reuses it.

So I think that's why you can't assign to a constant variable, is 
that there's no locating/initializing of new constant memory on 
the fly, to have a place to put that 24, 25, etc. Variables, even 
mutable variables, always have the same address, and any of us 
who are confused can think of assigment as a storage operation, 
more like erlang's "=>" rather than scheme's "(let)".

To "change" an address, you have to use a mutable pointer (or the 
like). The variable will always have the same address, but 
there's a second address stored at that address, and since the 
storage is mutable, that second address can be changed, by 
mutating the memory stored at the first address.

So like...

const(int)[2] a = [23,24];
const(int)* b = a;
writeln(&a," always constant");
writeln(a, " always constant");
writeln(a[0]," always constant");
writeln(&b," always constant");
writeln(b," always mutable");
writeln(*b, "constant");
b = b + 1;
writeln(*b, "also constant, but a different one.");

something like that...
Mar 23 2016
parent reply ag0aep6g <anonymous example.com> writes:
On 23.03.2016 21:52, cy wrote:
 const(int)[2] a = [23,24];
 const(int)* b = a;
Should be: const(int)* b = a.ptr;
 writeln(&a," always constant");
 writeln(a, " always constant");
There's some subtlety here. `a` itself is not const, but its elements are. `a` being a fixed-sized array, you can't actually change anything when the elements are not mutable. Things would be different with a dynamic array.
 writeln(a[0]," always constant");
 writeln(&b," always constant");
The address of a local variable isn't exactly const/immutable in the sense of the type system, I think. It simply doesn't change during the run of the function, and afterwards it's not considered alive anymore.
 writeln(b," always mutable");
 writeln(*b, "constant");
Yup and yup.
 b = b + 1;
Just to be 100% clear: you're adding to the pointer here, not to the value that's being pointed at. It's 24, because that's the second item in `a`. You can also allocate a whole new int and add set it to `*b + 1`. I think that's closer to your original goal. ---- b = new int(*b + 1); ----
 writeln(*b, "also constant, but a different one.");

 something like that...
Mar 23 2016
parent reply cy <dlang verge.info.tm> writes:
On Wednesday, 23 March 2016 at 21:10:49 UTC, ag0aep6g wrote:
 Just to be 100% clear: you're adding to the pointer here,
No, that's what I meant to do.
 b = new int(*b + 1);
Here "b" is pointing to mutable heap allocated data, which got cast to constant. with b = b + 1, it's still constant memory.
Mar 23 2016
parent reply ag0aep6g <anonymous example.com> writes:
On 23.03.2016 22:18, cy wrote:
 On Wednesday, 23 March 2016 at 21:10:49 UTC, ag0aep6g wrote:
[...]
 b = new int(*b + 1);
Here "b" is pointing to mutable heap allocated data, which got cast to constant. with b = b + 1, it's still constant memory.
It's stack memory. Its constness isn't any more physical than with `new`.
Mar 23 2016
parent ag0aep6g <anonymous example.com> writes:
On 23.03.2016 22:26, ag0aep6g wrote:
 On 23.03.2016 22:18, cy wrote:
 On Wednesday, 23 March 2016 at 21:10:49 UTC, ag0aep6g wrote:
[...]
 b = new int(*b + 1);
Here "b" is pointing to mutable heap allocated data, which got cast to constant. with b = b + 1, it's still constant memory.
It's stack memory. Its constness isn't any more physical than with `new`.
PS: You can also allocate an explicitly immutable int: ---- b = new immutable(int)(*b + 1); ----
Mar 23 2016