transporting qualifier from parameter to the return value
Steven Schveighoffer
schveiguy at yahoo.com
Sat Dec 19 20:16:32 PST 2009
On Wed, 16 Dec 2009 00:57:59 -0500, Walter Bright
<newshound1 at digitalmars.com> wrote:
> Steven Schveighoffer wrote:
>> type constructor. it has no meaning as a storage class since it's
>> entirely transient (it only has any meaning inside functions).
>
> I meant does it only apply at the top level, or does it apply down
> inside types?
I've been giving this some thought. inout is a strange beast, and it has
some interesting rules. For example, let's take a struct with an already
const member:
struct S
{
const(char)[] str;
}
Now, we have a function that uses inout on S:
inout(char)[] getStr(inout S s)
{
return s.str;
}
This should NOT compile, because if you pass in a mutable or immutable S,
then the compiler casts the result back to mutable or immutable! So inout
is transitive only for mutable members of data types. It's sort of
similar to applying const to a struct with an immutable member, the const
doesn't apply to the immutable member, only the mutable ones.
>
>> BTW, I'm unsure if U[inout(T)] should work.
>
> I just meant it as a compound type. It could as easily be:
>
> bar!(inout(T)) foo(inout X) { ... }
It might be workable. The only monkey wrench thrown in is that bar can do
conditional compilation based on the constancy of T:
template bar(T)
{
static if(is(T == const))
alias T[] bar;
else
struct bar { T t1, t2; }
}
This is no good, because you don't know how to build bar when your unsure
if T is const or not (which is the whole point of inout). If the compiler
can determine if bar!(T), bar!(const(T)), bar!(immutable(T)) and
bar!(inout(T)) generate identical code (except for the constancy of T),
then maybe it can forcibly cast the result once the return happens. This
might be the only time where inout can be applied to member variables
because it's a temporary situation inside an inout function.
It's a complex situation, one that probably requires a lot of thinking.
My recommendation at this time is to only allow bar!(inout(T)) if it is an
alias to something that normally would be returnable/passable to an inout
function e.g.:
template bar(T)
{
alias T[] bar;
}
as for AA's, it might be a case where we should allow it, since we know
AA's have the same implementation regardless of type info.
-Steve
More information about the Digitalmars-d
mailing list