WTF did happen with struct constructor and ref in 2.061 ?

Jonathan M Davis jmdavisProg at gmx.com
Fri Jan 4 12:59:32 PST 2013


On Friday, January 04, 2013 21:47:42 js.mdnq wrote:
> On Friday, 4 January 2013 at 16:47:38 UTC, Jonathan M Davis wrote:
> > On Friday, January 04, 2013 13:12:52 js.mdnq wrote:
> >> can you show an example of such a bug? I assume you mean that a
> >> "struct literal" ends up being a local object and a ref to it
> >> can
> >> easily become invalid?(in your example this is not possible
> >> inside main). But your example basically contradicts what you
> >> say.
> >> 
> >> There is no semantic difference between
> >> 
> >> S s = S(2); foo(s)
> >> 
> >> and
> >> 
> >> foo(S(2));
> > 
> > There's a _huge_ difference between those two. In the first
> > case, you have a
> > variable which exists beyond the end of the function call. In
> > the second, you
> > have temporary which is destroyed as soon as the statement has
> > completed.
> 
> Nope, sorry, it's not. That is only a compiler optimization. Just
> because the compiler decides to do something to make them
> different does not mean they are. The compiler could easily just
> make S(2) null for no obvious reason because it wants to.
> 
> But if the compiler decides to make a different because of some
> reason(such as optimization then it also can decide to not do so.
> 
> For example, tell me why the compiler can't just expand
> 
> foo(S(2));
> 
> to
> 
> S ___s = S(2);
> foo(___s)
> 
> where ___s is hidden?

S(2) _must_ leave scope after the statement foo(S(2)) completes, whereas with

S s = S(2);
foo(s);

the variable must continue to exist after foo(s) completes. That's 
fundamentally different. We're _not_ talking about compiler optimizations here. 
We're talking about the semantics of how the code works. And creating a 
variable on the stack would change the code's semantics, especially because 
foo(S(2)) should involve a move operation, whereas creating a variable on the 
stack would require that the object be destroyed after the call to foo. But 
even if declaring a hidden variable didn't change the semantics, __s must be 
destroyed once the statement with foo has completed, so it won't exist beyond 
the call to foo (it can't or it would alter the semantics of the code), so 
it's still fundamentally different from declaring a variable and passing it to 
foo, since the variable must continue to exist afterwards whereas the 
temporary must be gone.

- Jonathan M Davis


More information about the Digitalmars-d mailing list