Jump to page: 1 2
Thread overview
Global const variables
Oct 21, 2014
bearophile
Oct 21, 2014
Minas Mina
Oct 21, 2014
bearophile
Oct 21, 2014
safety0ff
Oct 21, 2014
Szymon Gatner
Oct 21, 2014
bearophile
Oct 21, 2014
Solomon E
Oct 21, 2014
anonymous
Oct 21, 2014
Solomon E
Oct 21, 2014
ketmar
Oct 21, 2014
Solomon E
Oct 21, 2014
ketmar
Oct 21, 2014
ketmar
Oct 21, 2014
MachineCode
Oct 21, 2014
Solomon E
Oct 21, 2014
Meta
Oct 21, 2014
Jonathan M Davis
Oct 21, 2014
Jonathan M Davis
Oct 21, 2014
Jonathan M Davis
October 21, 2014
Currently this code gets rejected:

const int[] a = [1];
void main() pure {
    auto y = a[0];
}


test2.d(3,14): Error: pure function 'D main' cannot access mutable static data 'a'
test2.d(3,14): Error: pure function 'D main' cannot access mutable static data 'a'

But is this a good idea? Isn't it better to accept it?

Bye,
bearophile
October 21, 2014
On Tuesday, 21 October 2014 at 08:02:52 UTC, bearophile wrote:
> Currently this code gets rejected:
>
> const int[] a = [1];
> void main() pure {
>     auto y = a[0];
> }
>
>
> test2.d(3,14): Error: pure function 'D main' cannot access mutable static data 'a'
> test2.d(3,14): Error: pure function 'D main' cannot access mutable static data 'a'
>
> But is this a good idea? Isn't it better to accept it?
>
> Bye,
> bearophile

Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it.
October 21, 2014
Minas Mina:

> Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it.

But how can main() not be pure? Or, how can't the 'a' array be immutable?

Bye,
bearophile
October 21, 2014
On Tuesday, 21 October 2014 at 08:25:07 UTC, bearophile wrote:
> Minas Mina:
>
>> Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it.
>
> But how can main() not be pure? Or, how can't the 'a' array be immutable?
>
> Bye,
> bearophile

There can exist a mutable reference to a's underlying memory:

const int[] a;
int[] b;

static this()
{
    b = [1];
    a = b;
}
October 21, 2014
On Tuesday, 21 October 2014 at 08:48:09 UTC, safety0ff wrote:
> On Tuesday, 21 October 2014 at 08:25:07 UTC, bearophile wrote:
>> Minas Mina:
>>
>>> Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it.
>>
>> But how can main() not be pure? Or, how can't the 'a' array be immutable?
>>
>> Bye,
>> bearophile
>
> There can exist a mutable reference to a's underlying memory:
>
> const int[] a;
> int[] b;
>
> static this()
> {
>     b = [1];
>     a = b;
> }

Ant this code works? What is the point of const then if you can assign it to mutable slice?

October 21, 2014
Szymon Gatner:

>> const int[] a;
>> int[] b;
>>
>> static this()
>> {
>>    b = [1];
>>    a = b;
>> }
>
> Ant this code works? What is the point of const then if you can assign it to mutable slice?

It works, and I think it should work. Inside the (module) constructor the const state is handled differently.

Thank you for the example, safety0ff.

Bye,
bearophile
October 21, 2014
On Tuesday, 21 October 2014 at 08:48:09 UTC, safety0ff wrote:
> On Tuesday, 21 October 2014 at 08:25:07 UTC, bearophile wrote:
>> Minas Mina:
>>
>>> Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it.
>>
>> But how can main() not be pure? Or, how can't the 'a' array be immutable?
>>
>> Bye,
>> bearophile
>
> There can exist a mutable reference to a's underlying memory:
>
> const int[] a;
> int[] b;
>
> static this()
> {
>     b = [1];
>     a = b;
> }

`a` isn't a reference to `b`. `a` is assigned by value and has its own storage. You could change its type to const int[]* a = &b; then it would be a reference to mutable storage. I made an example program to figure these things out, or else I wouldn't know what I'm talking about.

import std.stdio;
import std.conv;

const int[] a;
int[] b;

static this()
   {
        string entry;
        while(entry == "") {
            try {
                write("enter an int: ");
                entry = readln();
                b = [to!int(entry[0..entry.length-1])];
            } catch(ConvException e) {
                writeln("error, try again");
                entry = "";
            }
        }
        a = b;
    }

int[] x = [0,1,2,3];

class Holder
{
    const(int[]) y;
    this() { y = x; }
}

void main()
{
    auto H = new Holder();
    writeln("original const a ", a); // [the int that was entered]
    b = [8,7];
    writeln("unaltered const a ", a); // [the int that was entered]
    x = [10,9];
    writeln("unaltered const member y ", H.y); // [0, 1, 2, 3]
    H = new Holder();
    writeln("new const member y ", H.y); // [10, 9]
    writeln("immutable m ", get_m()); // [42]
}

immutable int[] m = [42];

immutable(int[]) get_m() pure
{
    return m;
}

October 21, 2014
On Tuesday, 21 October 2014 at 12:08:35 UTC, Solomon E wrote:
> On Tuesday, 21 October 2014 at 08:48:09 UTC, safety0ff wrote:
>> const int[] a;
>> int[] b;
>>
>> static this()
>> {
>>    b = [1];
>>    a = b;
>> }
>
> `a` isn't a reference to `b`. `a` is assigned by value and has its own storage.

`a` is indeed a copy of `b`. But `b` is a pointer+length, and
only those are copied. The array data is not copied. `a` and `b`
refer to the same data afterwards.

[...]
> const int[] a;
> int[] b;
>
> static this()
>    {
[...]
>         a = b;
>     }
>
[...]
>
> void main()
> {
[...]
>     b = [8,7];

Here, making `b` point somewhere else (to [8, 7]). If instead you
change b's elements, you'll see that `a` and `b` refer to the
same data:

b[] = 8; /* Will also change `a`'s data. */
October 21, 2014
On Tuesday, 21 October 2014 at 12:30:30 UTC, anonymous wrote:
> On Tuesday, 21 October 2014 at 12:08:35 UTC, Solomon E wrote:
>> On Tuesday, 21 October 2014 at 08:48:09 UTC, safety0ff wrote:
>>> const int[] a;
>>> int[] b;
>>>
>>> static this()
>>> {
>>>   b = [1];
>>>   a = b;
>>> }
>>
>> `a` isn't a reference to `b`. `a` is assigned by value and has its own storage.
>
> `a` is indeed a copy of `b`. But `b` is a pointer+length, and
> only those are copied. The array data is not copied. `a` and `b`
> refer to the same data afterwards.
>
> [...]
>> const int[] a;
>> int[] b;
>>
>> static this()
>>   {
> [...]
>>        a = b;
>>    }
>>
> [...]
>>
>> void main()
>> {
> [...]
>>    b = [8,7];
>
> Here, making `b` point somewhere else (to [8, 7]). If instead you
> change b's elements, you'll see that `a` and `b` refer to the
> same data:
>
> b[] = 8; /* Will also change `a`'s data. */

You're right. Thank you, anonymous stranger.

Sorry about that, safety0ff. It looks like you were right and I was wrong.

`b[0] = 8;` or `b[] = 8;` changes a. Printing the values for &a and &b shows they're different pointers, but (a is b) returns true. So I still have more to learn about how it does that.
October 21, 2014
On Tue, 21 Oct 2014 13:43:29 +0000
Solomon E via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> `b[0] = 8;` or `b[] = 8;` changes a. Printing the values for &a and &b shows they're different pointers, but (a is b) returns true. So I still have more to learn about how it does that.
that's 'cause '&b' taking address of hidden "array structure", not the first array element, as in C. try 'a.ptr' and 'b.ptr' to get addresses of array elements.


« First   ‹ Prev
1 2