ref parameters: there is no escape

Timon Gehr timon.gehr at gmx.ch
Tue Aug 16 09:00:31 PDT 2011


On 08/16/2011 05:33 AM, Mehrdad wrote:
> On 8/15/2011 2:04 PM, Timon Gehr wrote:
>> On 08/15/2011 04:04 PM, Mehrdad wrote:
>>> On 8/15/2011 4:10 AM, Timon Gehr wrote: Because now you need pointers
>>> to pass things by reference?
>> Only if the function intends to escape the reference. And if you
>> really need to, you can still use a cast.
>
> ... introducing D#?
>
> void dangerous(ref int x)
> {
> unsafe
> {
> bar(&x);
> }
> }
>
> (i.e. "you can still use a cast" is pretty much equivalent to using C#'s
> unsafe block. Maybe C#'s done some things correctly after all, huh?...)

Sure. I was never implying otherwise. But the main reason that in C# 
casts are not suitable for that kind of thing is that C# adopted the C 
cast syntax and that in a managed language, casts should always be safe.

>
>> Furthermore, escaping a reference is generally unsafe when it is to
>> stack memory (they can be some higher-level invariant that guarantees
>> safety, but that is not within the compilers reach -- use a cast.)
>
> Right, so let's also ban "auto ref" as a return value, since it could be
> returning the parameter itself, without the caller's knowledge:
>
> auto ref trySomethingExpensive(T)(auto ref T input, bool condition)
> {
> return condition ? doSomethingExpensive(input) : input; // Optimize the
> input
> }
>
> Thoughts? Should we ban ref return types, too?

Well obviously some measure to ban the improper usage of ref return 
types from safeD has to be taken eventually (otherwise safeD would not 
be memory safe, duh).

Basically the problem arises, when you directly pass on a reference you 
got from a function that took some of your local variables by ref (maybe 
indirectly through multiple ref returns). So that could be the construct 
to ban, which is less restrictive than banning ref return altogether.

>
>> When the reference is to a value type on heap memory, you had pointers
>> in your code all along.
> And that means...?

auto x=new int;
static assert(is(typeof(x)==int*));

Alternatively, you can use a wrapper class and then you don't need 
pointers at all.

> Java and C# have had pointers all along, but they're pretty darn
> successful at rendering them useless *except* for interop purposes.
> Obviously, it looks as though D is failing to achieve that same goal,
> requiring pointers for something so simple -- do we really want that?

D can still express everything that Java and C# can (and more) without 
allowing escaping ref argument addresses.

>
>> Warnings are issued for constructs that are regarded as potentially
>> dangerous/error-prone by many people, but are still valid code.
>> Therefore, they usually reflect suboptimal language design.
>
> Is that why my C compiler issues "Warning: Uninitialized local variable
> p" when I run this?
>
> int *p;
> *p = 5;
>
> AFAIK this is clearly *INVALID* (i.e. undefined) code according to the
> standard...

C is a machine-friendly language for writing lightning fast portable 
programs for arbitrary von Neumann architecture computers. Furthermore, 
writing a conformant compiler should be very easy. It does not need to 
be a well designed language, because that would interfer with other goals.

So if you are supposing I think the C language is well designed and 
warnings are useless for C, you are on the wrong path. It is the other 
way round. But it is really not a problem at all. I still like C. 
Usually, well designed languages have somewhat worse run-time 
characteristics.






More information about the Digitalmars-d mailing list