transporting qualifier from parameter to the return value
Steven Schveighoffer
schveiguy at yahoo.com
Tue Dec 15 21:09:32 PST 2009
On Tue, 15 Dec 2009 23:43:58 -0500, Walter Bright
<newshound1 at digitalmars.com> wrote:
> Andrei Alexandrescu wrote:
>> Time has come to make a decision on implementing Steven Schveighoffer's
>> proposal:
>
> Unmentioned in the proposal is is inout a type constructor or a storage
> class? For example,
>
> U[inout(T)]* foo(inout(X)*** p) { ... }
type constructor. it has no meaning as a storage class since it's
entirely transient (it only has any meaning inside functions). You should
never be able to declare any part of a global or member variable as inout,
because its meaning can change once a function exits. It's almost a beast
of it's own, it's mostly like const, but has some quirky extra rules.
BTW, I'm unsure if U[inout(T)] should work. Can one implicitly cast U[T]
to U[const(T)] ? If not, then it doesn't make sense that U[inout(T)]
should even compile. I guess the rule should be if you have a type that
contains an inout notation, the complier should verify that if you define
2 types, one that removes all inout decorations, called M, and one that
replaces all inout decorations with const, called N, you should be able to
cast from M to N implicitly. If not, then the inout type is invalid.
For example:
int[inout(char)[]]:
int[char[]] => M
int[const(char)[]] => N
>
> This is much more complex to implement than only allowing inout at the
> top level, i.e. as a storage class.
A storage class does not give you the transitivity that you need to
enforce const rules. The inout tag must be carried forth to aliases of
the same data.
>
> I also prefer the idea of inout on the return type being assumed, rather
> than explicit:
>
> T foo(inout U p) { ... }
What about this?
T[] foo(inout(U)[] p) {...}
Should the return type implicitly be inout(T)[] or inout T[] ?
-Steve
More information about the Digitalmars-d
mailing list