Bug 11307 – Make const(T).init and immutable(T).init lvalues

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-10-20T10:27:00Z
Last change time
2014-04-28T06:58:42Z
Assigned to
nobody
Creator
monarchdodra

Comments

Comment #0 by monarchdodra — 2013-10-20T10:27:04Z
".init" is a global property, that is marked as rvalue, to prevent it being modified. This is correct behavior. However, when "T" is const/immutable already, then it is illegal to modify it anyways. Making ".init" an lvalue for such cases has advantages. First, when writing "foo(const(T).init)", or "tmp = const(T).init", then pass by const reference will be preferred over pass by value. Second, a "common" use case, to memcpy initialize. This usually looks something like: T tmp = void; immutable(T) init = immutable(T).init; memcpy(&tmp, &init, T.sizeof); Making a local copy (on the stack, or in static space) is gratuitous, and can be avoided entirelly. This should work: T tmp = void; memcpy(&tmp, &immutable(T).init, T.sizeof); This code actually happens relatively often, in array and appender. So that's the ER. Nothing huge. Just keeping the T.init lvalue if T is const (or immutable). There's no reason to make it rvalue.
Comment #1 by andrej.mitrovich — 2014-04-26T19:02:13Z
Does lvalueOf help with this?
Comment #2 by monarchdodra — 2014-04-26T20:56:05Z
(In reply to Andrej Mitrovic from comment #1) > Does lvalueOf help with this? Not really. All `lvalueOf` does is provide an "external" lvalue you can test for your traits/contraints, but it doesn't actually provide an actual instance you can read or use.
Comment #3 by k.hara.pg — 2014-04-28T05:15:08Z
(In reply to monarchdodra from comment #0) > ".init" is a global property, that is marked as rvalue, to prevent it being > modified. This is correct behavior. > > However, when "T" is const/immutable already, then it is illegal to modify > it anyways. Making ".init" an lvalue for such cases has advantages. Not only to prevent its modification, T.init makes an rvalue to prevent copy construction on its usage. auto t = T.init; If T.init returns an lvalue, initializing t will always invoke T's postblit if exists.
Comment #4 by monarchdodra — 2014-04-28T06:58:42Z
(In reply to Kenji Hara from comment #3) > (In reply to monarchdodra from comment #0) > > ".init" is a global property, that is marked as rvalue, to prevent it being > > modified. This is correct behavior. > > > > However, when "T" is const/immutable already, then it is illegal to modify > > it anyways. Making ".init" an lvalue for such cases has advantages. > > Not only to prevent its modification, T.init makes an rvalue to prevent copy > construction on its usage. > > auto t = T.init; > > If T.init returns an lvalue, initializing t will always invoke T's postblit > if exists. I think that's good enough of a reason to not implement this.