Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 29, 2010 std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Attachments:
| Hi, in std.algorithm move(), this is the operation used to set the source of a struct move to .init: static T empty; memcpy(&source, &empty, T.sizeof); Is there any particular reason why the more compact &T.init is not used? |
August 29, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Posted in reply to Torarin | Torarin wrote:
> Hi,
> in std.algorithm move(), this is the operation used to set the source of a struct move to .init:
>
> static T empty;
> memcpy(&source, &empty, T.sizeof);
>
> Is there any particular reason why the more compact &T.init is not used?
>
I may be wrong, but it seems that in this case T.init will yield a temporary, while static T empty is 'always' there.
Consider:
struct S {}
void main()
{
writefln("%x", &S.init); // prints one value
writefln("%x", &S.init); // prints another value
static S s;
writefln("%x", &s); // prints one value
writefln("%x", &s); // prints the same value
}
|
August 29, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | Yes, you are right!
Looking at the assembly, T.init creates a struct on the stack.
2010/8/29 Stanislav Blinov <stanislav.blinov@gmail.com>
>
> Torarin wrote:
>>
>> Hi,
>> in std.algorithm move(), this is the operation used to set the source of a struct move to .init:
>>
>> static T empty;
>> memcpy(&source, &empty, T.sizeof);
>>
>> Is there any particular reason why the more compact &T.init is not used?
>>
>
> I may be wrong, but it seems that in this case T.init will yield a temporary, while static T empty is 'always' there.
>
> Consider:
>
> struct S {}
>
> void main()
> {
> writefln("%x", &S.init); // prints one value
> writefln("%x", &S.init); // prints another value
>
> static S s;
>
> writefln("%x", &s); // prints one value
> writefln("%x", &s); // prints the same value
> }
|
August 29, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Posted in reply to Torarin | On 08/29/2010 12:00 PM, Torarin wrote:
> Hi,
> in std.algorithm move(), this is the operation used to set the source of
> a struct move to .init:
>
> static T empty;
> memcpy(&source, &empty, T.sizeof);
>
> Is there any particular reason why the more compact &T.init is not used?
T.init is not guaranteed to be an lvalue.
Andrei
|
August 29, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Even in this case, or in some special case? Torarin 2010/8/29 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>: > On 08/29/2010 12:00 PM, Torarin wrote: >> >> Hi, >> in std.algorithm move(), this is the operation used to set the source of >> a struct move to .init: >> >> static T empty; >> memcpy(&source, &empty, T.sizeof); >> >> Is there any particular reason why the more compact &T.init is not used? > > T.init is not guaranteed to be an lvalue. > > Andrei > |
August 30, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
On Sunday, August 29, 2010 11:51:51 Torarin wrote:
> Even in this case, or in some special case?
>
> Torarin
>
> 2010/8/29 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:
> > On 08/29/2010 12:00 PM, Torarin wrote:
> >> Hi,
> >> in std.algorithm move(), this is the operation used to set the source of
> >> a struct move to .init:
> >>
> >> static T empty;
> >> memcpy(&source, &empty, T.sizeof);
> >>
> >> Is there any particular reason why the more compact &T.init is not used?
> >
> > T.init is not guaranteed to be an lvalue.
> >
> > Andrei
T.init cannot be set. It's a fixed value. When you use it, you're typically going to be copying it to an lvalue or creating a temporary. Temporaries aren't lvalues. So, T.init can be assigned to an lvalue, but it isn't itself an lvalue.
- Jonathan M Davis
|
August 30, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Currently you can take its address, so doesn't that mean that it's an lvalue?
2010/8/30 Jonathan M Davis <jmdavisprog@gmail.com>:
> On Sunday, August 29, 2010 11:51:51 Torarin wrote:
>> Even in this case, or in some special case?
>>
>> Torarin
>>
>> 2010/8/29 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:
>> > On 08/29/2010 12:00 PM, Torarin wrote:
>> >> Hi,
>> >> in std.algorithm move(), this is the operation used to set the source of
>> >> a struct move to .init:
>> >>
>> >> static T empty;
>> >> memcpy(&source, &empty, T.sizeof);
>> >>
>> >> Is there any particular reason why the more compact &T.init is not used?
>> >
>> > T.init is not guaranteed to be an lvalue.
>> >
>> > Andrei
>
> T.init cannot be set. It's a fixed value. When you use it, you're typically going to be copying it to an lvalue or creating a temporary. Temporaries aren't lvalues. So, T.init can be assigned to an lvalue, but it isn't itself an lvalue.
>
> - Jonathan M Davis
>
|
August 30, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Posted in reply to Torarin | Torarin wrote:
>> T.init cannot be set. It's a fixed value. When you use it, you're typically going
>> to be copying it to an lvalue or creating a temporary. Temporaries aren't
>> lvalues. So, T.init can be assigned to an lvalue, but it isn't itself an lvalue.
>>
>> - Jonathan M Davis
>>
> Currently you can take its address, so doesn't that mean that it's an lvalue?
No, you can't. Generally, that is.
For example:
enum A
{
a,
b
}
void main()
{
void* p = &A.init; // won't compile
}
You may be able to take address of what .init returns, but what Andrei meant by 'it is not guaranteed' means that this is not always the case. So basically, you should not rely on the cases when you can do that.
That's why I was wrong, also. The case wasn't about temporaries at all :)
|
August 30, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | Yeah, I get the enum case, but what I forgot to mention is that the
example from move() is enclosed in
static if (is(T == struct))
Which makes me wonder what kind of struct would have an rvalue .init.
Torarin
2010/8/30 Stanislav Blinov <stanislav.blinov@gmail.com>:
> You may be able to take address of what .init returns, but what Andrei meant by 'it is not guaranteed' means that this is not always the case. So basically, you should not rely on the cases when you can do that.
>
> That's why I was wrong, also. The case wasn't about temporaries at all :)
>
|
August 31, 2010 Re: std.algorithm move() struct emptying | ||||
---|---|---|---|---|
| ||||
31.08.2010 0:27, Torarin wrote:
> Yeah, I get the enum case, but what I forgot to mention is that the
> example from move() is enclosed in
> static if (is(T == struct))
>
> Which makes me wonder what kind of struct would have an rvalue .init.
>
I don't know, maybe the one that's not invented yet ;)
|
Copyright © 1999-2021 by the D Language Foundation