An interesting consequence of safety requirements

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Nov 4 11:14:47 PST 2009


Leandro Lucarella wrote:
> Andrei Alexandrescu, el  4 de noviembre a las 11:24 me escribiste:
>> 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).
> 
> Or maybe th compiler should rewrite local.prepend(lst); as:
> auto this_ = &local;
> f(*_this);
> 
> Then the compiler can detect when taking the address of local is not
> legal as it will do if you write the function as static.
> 

Yah, but how would the compiler decide (in a separate compilation 
approach) that some functions are actually fine?

// inside List(T)
T getPayload() {
     return payload;
}


Andrei



More information about the Digitalmars-d mailing list