View mode: basic / threaded / horizontal-split · Log in · Help
January 16, 2010
Why it doesn't compile in D 2.0?
class Test {
    string t1 = "test";		//Ok!
    char[] t2 = "test".dup;	//Compile error
}

void main(char[][] args) {
}

Error:
hello.d(3): Error: cannot evaluate _adDupT((& 
D12TypeInfo_Aya6__initZ),"test") at compile time
hello.d(3): Error: cannot evaluate _adDupT((& 
D12TypeInfo_Aya6__initZ),"test") at compile time

Is there workaround?

BR
Marcin Kuszczak
(aarti_pl)
January 16, 2010
Re: Why it doesn't compile in D 2.0?
aarti_pl <aarti@interia.pl> wrote:

>
> class Test {
>      string t1 = "test";		//Ok!
>      char[] t2 = "test".dup;	//Compile error
> }
>
> void main(char[][] args) {
> }
>
> Error:
> hello.d(3): Error: cannot evaluate _adDupT((&  
> D12TypeInfo_Aya6__initZ),"test") at compile time
> hello.d(3): Error: cannot evaluate _adDupT((&  
> D12TypeInfo_Aya6__initZ),"test") at compile time
>
> Is there workaround?

Constant strings are saved in the static data segment of the executable, so
the .dup call would need to be executed at runtime. In other words, what
this would do is cast const to mutable.

If this did compile, changing the contents of t2 would change those  
contents
for all instances of Test, which I assume is not your intention.

As for the workaround, write a constructor:

class Test {
  string t1 = "test";
  string t2;

  this( ) {
    t2 = "test".dup;
  }
}

-- 
Simen
January 16, 2010
Re: Why it doesn't compile in D 2.0?
W dniu 2010-01-16 13:26, Simen kjaeraas pisze:
> aarti_pl <aarti@interia.pl> wrote:
>
>>
>> class Test {
>> string t1 = "test"; //Ok!
>> char[] t2 = "test".dup; //Compile error
>> }
>>
>> void main(char[][] args) {
>> }
>>
>> Error:
>> hello.d(3): Error: cannot evaluate _adDupT((&
>> D12TypeInfo_Aya6__initZ),"test") at compile time
>> hello.d(3): Error: cannot evaluate _adDupT((&
>> D12TypeInfo_Aya6__initZ),"test") at compile time
>>
>> Is there workaround?
>
> Constant strings are saved in the static data segment of the executable, so
> the .dup call would need to be executed at runtime. In other words, what
> this would do is cast const to mutable.
>
> If this did compile, changing the contents of t2 would change those
> contents
> for all instances of Test, which I assume is not your intention.
>
> As for the workaround, write a constructor:
>
> class Test {
> string t1 = "test";
> string t2;
>
> this( ) {
> t2 = "test".dup;
> }
> }
>

I want just simple initialization of variable. Casting of course is no 
(sane) option.

Indeed, in case of classes your workaround will work.

But in case of struct? The same problem occurs for structs, but you can 
not declare default constructor in structs...

IMHO .dup should work for initialization of classes/structs.

Any other ideas?

BR
Marcin Kuszczak
(aarti_pl)
January 16, 2010
Re: Why it doesn't compile in D 2.0?
On 01/16/2010 02:01 PM, aarti_pl wrote:
> W dniu 2010-01-16 13:26, Simen kjaeraas pisze:
>> aarti_pl <aarti@interia.pl> wrote:
>>
>>>
>>> class Test {
>>> string t1 = "test"; //Ok!
>>> char[] t2 = "test".dup; //Compile error
>>> }
>>>
>>> void main(char[][] args) {
>>> }
>>>
>>> Error:
>>> hello.d(3): Error: cannot evaluate _adDupT((&
>>> D12TypeInfo_Aya6__initZ),"test") at compile time
>>> hello.d(3): Error: cannot evaluate _adDupT((&
>>> D12TypeInfo_Aya6__initZ),"test") at compile time
>>>
>>> Is there workaround?
>>
>> Constant strings are saved in the static data segment of the
>> executable, so
>> the .dup call would need to be executed at runtime. In other words, what
>> this would do is cast const to mutable.
>>
>> If this did compile, changing the contents of t2 would change those
>> contents
>> for all instances of Test, which I assume is not your intention.
>>
>> As for the workaround, write a constructor:
>>
>> class Test {
>> string t1 = "test";
>> string t2;
>>
>> this( ) {
>> t2 = "test".dup;
>> }
>> }
>>
>
> I want just simple initialization of variable. Casting of course is no
> (sane) option.
>
> Indeed, in case of classes your workaround will work.
>
> But in case of struct? The same problem occurs for structs, but you can
> not declare default constructor in structs...
>
> IMHO .dup should work for initialization of classes/structs.
>
> Any other ideas?
>
> BR
> Marcin Kuszczak
> (aarti_pl)

Perhaps this is or should be a bug. You can override dup to work in ctfe:

char[] dup(string str)
{
    return str.dup;
}

class Test {
    string t1 = "test";        //Ok!
    char[] t2 = "test".dup;    //Compile error
    char[] t3 = "test".dup();  //Ok!
}

The spec even mentions it under ctfe:

6. as a special case, the following properties can be executed at 
compile time:
.dup
.length
.keys
.values

http://www.digitalmars.com/d/2.0/function.html
January 16, 2010
Re: Why it doesn't compile in D 2.0?
W dniu 2010-01-16 15:30, Lutger pisze:
>
> Perhaps this is or should be a bug. You can override dup to work in ctfe:
>
> char[] dup(string str)
> {
> return str.dup;
> }
>
> class Test {
> string t1 = "test"; //Ok!
> char[] t2 = "test".dup; //Compile error
> char[] t3 = "test".dup(); //Ok!
> }
>
> The spec even mentions it under ctfe:
>
> 6. as a special case, the following properties can be executed at
> compile time:
> ..dup
> ..length
> ..keys
> ..values
>
> http://www.digitalmars.com/d/2.0/function.html
>

Thanks! I will use function dup() as a workaround for now, and will put 
bug to bugzilla.

I still wonder what has CTFE to do with this case. Do you know?

I am asking because it's not possible in general case to initialize all 
variables in classes/structs and in global namespace.
E.g. I had to use:

Serializer!(TextArchive) serializer;
static this() {
    serializer = new typeof(serializer);
}

to initialize serializer. I am wondering if with better CTFE we could 
get it working?

BR
Marcin Kuszczak
(aarti_pl)
January 16, 2010
Re: Why it doesn't compile in D 2.0?
On 01/16/2010 04:18 PM, aarti_pl wrote:
> W dniu 2010-01-16 15:30, Lutger pisze:
>>
>> Perhaps this is or should be a bug. You can override dup to work in ctfe:
>>
>> char[] dup(string str)
>> {
>> return str.dup;
>> }
>>
>> class Test {
>> string t1 = "test"; //Ok!
>> char[] t2 = "test".dup; //Compile error
>> char[] t3 = "test".dup(); //Ok!
>> }
>>
>> The spec even mentions it under ctfe:
>>
>> 6. as a special case, the following properties can be executed at
>> compile time:
>> ..dup
>> ..length
>> ..keys
>> ..values
>>
>> http://www.digitalmars.com/d/2.0/function.html
>>
>
> Thanks! I will use function dup() as a workaround for now, and will put
> bug to bugzilla.
>
> I still wonder what has CTFE to do with this case. Do you know?
>
> I am asking because it's not possible in general case to initialize all
> variables in classes/structs and in global namespace.
> E.g. I had to use:
>
> Serializer!(TextArchive) serializer;
> static this() {
> serializer = new typeof(serializer);
> }
>
> to initialize serializer. I am wondering if with better CTFE we could
> get it working?
>
> BR
> Marcin Kuszczak
> (aarti_pl)

ctfe is basically a user defined extension of constant folding, which is 
also mentioned in the spec that way. So to use it for more complex 
initialization makes sense, but this is constrained to compile time. 
From the example of the serializer, all we know is that it allocates 
memory. Array dup-ing also allocates memory however, so theoretically I 
see no immediate reason why it would not (eventually) be possible to use 
ctfe in that case. But it may be difficult to prove statically by the 
compiler that it is indeed safe to do so.
January 17, 2010
Re: Why it doesn't compile in D 2.0?
Lutger <lutger.blijdestijn@gmail.com> wrote:

> Perhaps this is or should be a bug. You can override dup to work in ctfe:
>
> char[] dup(string str)
> {
>      return str.dup;
> }
>
> class Test {
>      string t1 = "test";        //Ok!
>      char[] t2 = "test".dup;    //Compile error
>      char[] t3 = "test".dup();  //Ok!
> }

The problem with this approach is that you now have a pointer to mutable
data, the contents of which are stored in the static data segment, and thus
actually immutable.

Second (and this is related to the first), the pointer will be the same for
all instances, and thus changing the contents of one will change the
contents of all.

IOW, what one (probably) wants in this situation, is a constructor.

-- 
Simen
January 17, 2010
Re: Why it doesn't compile in D 2.0?
aarti_pl wrote:
> W dniu 2010-01-16 15:30, Lutger pisze:
>>
>> Perhaps this is or should be a bug. You can override dup to work in ctfe:
>>
>> char[] dup(string str)
>> {
>> return str.dup;
>> }
>>
>> class Test {
>> string t1 = "test"; //Ok!
>> char[] t2 = "test".dup; //Compile error
>> char[] t3 = "test".dup(); //Ok!
>> }
>>
>> The spec even mentions it under ctfe:
>>
>> 6. as a special case, the following properties can be executed at
>> compile time:
>> ..dup
>> ..length
>> ..keys
>> ..values
>>
>> http://www.digitalmars.com/d/2.0/function.html
>>
> 
> Thanks! I will use function dup() as a workaround for now, and will put 
> bug to bugzilla.
> 
> I still wonder what has CTFE to do with this case. Do you know?
> 
> I am asking because it's not possible in general case to initialize all 
> variables in classes/structs and in global namespace.
> E.g. I had to use:
> 
> Serializer!(TextArchive) serializer;
> static this() {
>     serializer = new typeof(serializer);
> }
> 
> to initialize serializer. I am wondering if with better CTFE we could 
> get it working?
> 
> BR
> Marcin Kuszczak
> (aarti_pl)

The next DMD release will have *major* CTFE improvements. I believe this 
will work in the next release. (D1 couldn't compile it before, it can 
now; I think D2 will be the same).
January 17, 2010
Re: Why it doesn't compile in D 2.0?
On 01/17/2010 01:38 AM, Simen kjaeraas wrote:
> Lutger <lutger.blijdestijn@gmail.com> wrote:
>
>> Perhaps this is or should be a bug. You can override dup to work in ctfe:
>>
>> char[] dup(string str)
>> {
>> return str.dup;
>> }
>>
>> class Test {
>> string t1 = "test"; //Ok!
>> char[] t2 = "test".dup; //Compile error
>> char[] t3 = "test".dup(); //Ok!
>> }
>
> The problem with this approach is that you now have a pointer to mutable
> data, the contents of which are stored in the static data segment, and thus
> actually immutable.
>
> Second (and this is related to the first), the pointer will be the same for
> all instances, and thus changing the contents of one will change the
> contents of all.
>
> IOW, what one (probably) wants in this situation, is a constructor.
>


Thanks man, this is a big error of mine. Trying to manipulate the char[] 
does indeed do a segfault! I can't seem to find an explanation in the 
spec of how initializers are supposed to work, so I assumed incorrectly 
it would be ok.

I find it a bit disturbing that you can end up with a mutable reference 
to immutable data so easily, without casting or anything.
January 17, 2010
Re: Why it doesn't compile in D 2.0?
aarti_pl wrote:
> 
> class Test {
>     string t1 = "test";        //Ok!
>     char[] t2 = "test".dup;    //Compile error
> }
> 
> void main(char[][] args) {
> }
> 
> Error:
> hello.d(3): Error: cannot evaluate _adDupT((& 
> D12TypeInfo_Aya6__initZ),"test") at compile time
> hello.d(3): Error: cannot evaluate _adDupT((& 
> D12TypeInfo_Aya6__initZ),"test") at compile time
> 
> Is there workaround?
> 
> BR
> Marcin Kuszczak
> (aarti_pl)

Workaround: It works in dmd2, svn 337 and later <g>.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home