An interesting consequence of safety requirements

Chad J chadjoan at __spam.is.bad__gmail.com
Wed Nov 4 23:56:49 PST 2009


Andrei Alexandrescu wrote:
> Something just dawned on me: in safe mode, struct static member
> functions will be preferred to struct non-static member functions.
> 
> Why?
> 
> Consider:
> 
> struct List(T) {
>     T payload;
>     List * next;
> 
>     void prepend(List * newNode) {
>         newNode.next = &this;
>     }
> }
> 
> This code can't make it in safe mode because it takes the address of
> this. In general, the compiler must assume that you might have created a
> List object on the stack, e.g.:
> 
> List * someFun() {
>     List local;
>     List * lst = new List;
>     local.prepend(lst);
>     return lst;
> }
> 
> Now even if there is no ostensible local address taking, the code is in
> error because it has escaped the address of a local.
> 
> So prepend() cannot be compiled. The way to make it compile in safe mode
> is:
> 
> 
> struct List(T) {
>     T payload;
>     List * next;
> 
>     static void prepend(List * zis, List * newNode) {
>         newNode.next = zis;
>     }
> }
> 
> Now the code compiles and is actually safe because it is impossible to
> pass the address of a local into prepend.
> 
> So get ready to use static a lot more ;o).
> 
> 
> Andrei

This looks to me like it implicates ref parameters in general.

> struct List(T) {
>     T payload;
>     List * next;
>
>     void prepend(List * newNode) {
>         newNode.next = &this;
>     }
> }

could be written as

struct List(T) {
    T payload;
    List * next;

    static void prepend(ref List zis, List * newNode) {
        newNode.next = &zis;
    }
}

It's not the same as the other static version, since zis is a ref and
not a pointer.

List * someFun() {
    List local;
    List * lst = new List;
    prepend(local,lst);    // <-- dubious; local is trying to hide
    return lst;            // <-- he got away
}

I think in the general case there might need to be some way to track
functions that have ref parameters.

Perhaps any ref parameter that has its address taken is marked as being
unable to accept local variables as arguments.  Additionally, it should
also not accept a parent function's ref parameters as arguments, since
those could be local to someone else.  Then if you rewrite member
functions as static versions with ref parameters as the zeroth arg, they
 will benefit from the analysis as well.

Maybe this is too complicated.  If not, hope it helps.



More information about the Digitalmars-d mailing list