Public outcry against new .init behaviour

Deewiant deewiant.doesnotlike.spam at gmail.com
Mon Jul 2 21:08:42 PDT 2007


Sean Kelly wrote:
> For what it's worth, I actually had no idea that t.init was different
> from T.init.  I must have simply overlooked it in the spec.  But while
> it is an appealing idea, it presents tradeoffs that are perhaps not
> ideal.  If the actual initialization value must be retained, then space
> must be reserved for it in functions where "t.init" is used.  And it
> seems like this behavior could possibly change based on scope?  ie.
> 
>     void fnA() {
>         int x = 5;
>         assert( fnB( x ) == x.init );
>     }
> 
>     void fnB( inout int x ) {
>         return x.init;
>     }
> 
> Will the above pass or fail?
> 
> Alternately, if space is not reserved for the init value, then the
> initializer must be run every time "t.init" is called.  But what if this
> initializer has side effects?  This is clearly not an acceptable solution.
> 

The code will fail, because x.init here is the .init of x in that scope. Here,
it's always typeof(x).init, but if the x in the parameter list were to have a
default initializer (doesn't work in the case of inout), x.init would be that:

void fnB(int x = 3) { /+ x.init is 3 +/ }

A good rule is that if a variable is initialized to a compile-time constant,
variable.init is that constant. Otherwise, variable.init is
typeof(variable).init. (My terminology might be a bit wrong: it's not the
variable, it's the symbol of a variable in a scope? Whatever works so that it
explains function parameters, too.)

I wouldn't mind if variable.init were an error in the latter cases, but the
above rule can be used to always figure out what it means.

(To be pedantic, your code will fail also because fnB returns void.)

-- 
Remove ".doesnotlike.spam" from the mail address.



More information about the Digitalmars-d mailing list