Jump to page: 1 2 3
Thread overview
Can I call the default opAssign after overloading opAssign?
Nov 16, 2012
Rob T
Nov 17, 2012
Jonathan M Davis
Nov 17, 2012
Kagamin
Nov 17, 2012
Jonathan M Davis
Nov 19, 2012
Rob T
Nov 19, 2012
Jonathan M Davis
Nov 19, 2012
Rob T
Nov 19, 2012
Jonathan M Davis
Nov 19, 2012
Rob T
Nov 19, 2012
Jonathan M Davis
Nov 19, 2012
Rob T
Nov 19, 2012
Andrej Mitrovic
Nov 19, 2012
Dan
Nov 23, 2012
Dan
Nov 23, 2012
Rob T
Nov 24, 2012
Era Scarecrow
Nov 24, 2012
Dan
Nov 25, 2012
Rob T
Nov 25, 2012
monarch_dodra
Nov 25, 2012
Dan
Nov 25, 2012
Jonathan M Davis
November 16, 2012
My understanding is that a struct will have a default postblit opAssign. What I want to know is if I can call the default opAssign after overriding it, or is it inaccessible?

I know that I do not have to execute the default after overriding, but if I can call it, I'd like to know because in some cases it may be useful to run the default. So this is just a general knowledge kind of question at this point.

--rt


November 17, 2012
On Friday, November 16, 2012 21:31:26 Rob T wrote:
> My understanding is that a struct will have a default postblit opAssign. What I want to know is if I can call the default opAssign after overriding it, or is it inaccessible?
> 
> I know that I do not have to execute the default after overriding, but if I can call it, I'd like to know because in some cases it may be useful to run the default. So this is just a general knowledge kind of question at this point.

I don't think that it even exists. Basically, if you don't define an opAssign, one is provided for you. If you do define one, then you already have one, so the compiler doesn't provide one.

- Jonathan M Davis
November 17, 2012
AFAIK, opAssign and postblit are different operators. Postblit is called after blit, and opAssign is called instead of blit.
November 17, 2012
On Saturday, November 17, 2012 15:33:48 Kagamin wrote:
> AFAIK, opAssign and postblit are different operators. Postblit is called after blit, and opAssign is called instead of blit.

postlbit is making a new copy of an object, whereas opAssign is replacing the state of a pre-existing object. They're fundamentally different.

- Jonathan M Davis
November 19, 2012
I assume that when I define an opAssign, only the opAssign that I define gets called, which means there's no blit or postblit being called ever again.

I may be thoroughly confused at this point. Is there both a blit and a postblit, and an optional opAssign that when specified will override both?

--rt
November 19, 2012
On Monday, November 19, 2012 06:01:55 Rob T wrote:
> I assume that when I define an opAssign, only the opAssign that I define gets called, which means there's no blit or postblit being called ever again.
> 
> I may be thoroughly confused at this point. Is there both a blit and a postblit, and an optional opAssign that when specified will override both?

postblit constructors and opAssign aren't really related. The postblit constructor is used when a _new_ instance is being constructed (it plays the same role as a copy constructor in C++). opAssign overloads the assignment operator and is only used when the assignment operator is used, which does _not_ happen when contstructing a new instance but only when replacing the value of an instance with that of another.

S s1;
S s2 = s1; // postblit
s1 = s2; // opAssign
foo(s1); // postblit

If you don't define a postblit constructor, then when a new instance is created from another, then the original is memcpyed/blitted to the new one. If you _do_ define a postblit constructor, then the original is memcpyed/blitted and then _after_ that the postblit constructor is called so that you have the opportunity to deep copy the pieces that need to be deep copied.

If you don't define opAssign, then when assigning from the one instance to another, a memcpy/blit is done to copy the data over. If you _do_ define a opAssign, then no memcpy/blit is made at all, but rather opAssign is called.

- Jonathan M Davis
November 19, 2012
I think you've cleared things up for me.

When I define an opAssign, I'm not really overriding a default opAssign, because there is none, instead I'm overriding the default behavior which is to perform a memcopy-like operation.

So if I defined an opAssign function, but for some odd reason I wanted to execute the default assignment behavior, then I can still do it by performing a memcopy-like operation, perhaps best done using the C libs memcopy function.

Correct?

--rt
November 19, 2012
On Monday, November 19, 2012 07:21:10 Rob T wrote:
> I think you've cleared things up for me.
> 
> When I define an opAssign, I'm not really overriding a default opAssign, because there is none, instead I'm overriding the default behavior which is to perform a memcopy-like operation.
> 
> So if I defined an opAssign function, but for some odd reason I wanted to execute the default assignment behavior, then I can still do it by performing a memcopy-like operation, perhaps best done using the C libs memcopy function.
> 
> Correct?

I'm not sure. Close certainly. But if any member variables define an opAssign, then the compiler probably calls them rather than doing a simple memcpy. I'm not sure though. If it does, then a memcpy would not exhibit the same behavior, and the only way to get the same behavior would be to copy each member variable one by one. If it doesn't, then a memcpy would do the same thing as the default behavior.

I am a bit worried though as to why you'd even want to skip opAssign like that. At the moment, I can't think of any legitimate use cases for doing that (though that obviously doesn't mean that you don't have one).

- Jonathan M Davis
November 19, 2012
On Monday, 19 November 2012 at 06:32:56 UTC, Jonathan M Davis wrote:
> I'm not sure. Close certainly. But if any member variables define an opAssign,
> then the compiler probably calls them rather than doing a simple memcpy. I'm
> not sure though. If it does, then a memcpy would not exhibit the same
> behavior, and the only way to get the same behavior would be to copy each
> member variable one by one. If it doesn't, then a memcpy would do the same
> thing as the default behavior.

I think you are right. There's was a post a couple days ago on an issue concerning a nested struct with opAssign. The parent had no opAssign, but the nested struct did, and for some reason the nested opAssign was not being called in one case, but was being called in another. Something about being relocatable?

> I am a bit worried though as to why you'd even want to skip opAssign like
> that. At the moment, I can't think of any legitimate use cases for doing that
> (though that obviously doesn't mean that you don't have one).
>
> - Jonathan M Davis

No reason I can see at this time either. I just want to fully understand what D is doing because it's not clearly documented. What worries me most, is if I end up relying on behaviors that end up being implemented as clever compiler optimizations rather than being a part of the D language specification (which is currently MIA).

--rt

November 19, 2012
On Monday, November 19, 2012 10:29:21 Rob T wrote:
> the D language specification (which is currently MIA).

The online documentation _is_ the official spec, though it definitely doesn't have enough detail to be unambiguous, and in some cases, it's not properly up- to-date.

- Jonathan M Davis
« First   ‹ Prev
1 2 3