safety model in D

Michal Minich michal at minich.sk
Wed Nov 4 07:43:26 PST 2009


Hello Don,

> Michal Minich wrote:
> 
>> Hello Michel,
>> 
>>> I'm not sure this works so well. Look at this:
>>> 
>>> module memory;   // unsafe interface - unsafe impl.
>>> extern (C) void* malloc(int);
>>> extern (C) void free(void*);
>>> module (system) my.system;   // safe interface - unsafe impl.
>>> import memory;
>>> void test() { auto i = malloc(10); free(i); }   // ok: unsafe impl.
>>> allowed
>>> module (safe) my.safe;   // safe interface - safe impl.
>>> import memory;
>>> void test() { auto i = malloc(10); free(i); }   // error: malloc,
>>> free
>>> are unsafe
>>> How is this supposed to work correctly with and without the "-safe"
>>> compiler flag? The way you define things "-safe" would make module
>>> memory safe for use while it is not.
>> I'm saying the module memory would not compile when compiler is
>> called with -safe switch.
>> 
>> the compiler would try to compile each module without safety
>> specification, as if they were *marked* (safe) - which will not
>> succeed for module memory in this case.
>> 
>> In this setting, the reasons to have -safe compiler switch are not so
>> important, they are more like convenience, meaning more like
>> -forcesafe. You would want to use this flag only when you *need* to
>> make sure your application is safe, usually when you are using other
>> libraries. By this switch you can prevent compilation of unsafe
>> application in case some other library silently changes safe module
>> to unsafe in newer version.
>> 
> Doesn't work. There are system modules which CANNOT safely be called
> from safe modules -- eg extern(C) functions. They MUST have unsafe
> interfaces.
> 

Hello Don,

> Michal Minich wrote:
> 
>> Hello Michel,
>> 
>>> I'm not sure this works so well. Look at this:
>>> 
>>> module memory;   // unsafe interface - unsafe impl.
>>> extern (C) void* malloc(int);
>>> extern (C) void free(void*);
>>> module (system) my.system;   // safe interface - unsafe impl.
>>> import memory;
>>> void test() { auto i = malloc(10); free(i); }   // ok: unsafe impl.
>>> allowed
>>> module (safe) my.safe;   // safe interface - safe impl.
>>> import memory;
>>> void test() { auto i = malloc(10); free(i); }   // error: malloc,
>>> free
>>> are unsafe
>>> How is this supposed to work correctly with and without the "-safe"
>>> compiler flag? The way you define things "-safe" would make module
>>> memory safe for use while it is not.
>> I'm saying the module memory would not compile when compiler is
>> called with -safe switch.
>> 
>> the compiler would try to compile each module without safety
>> specification, as if they were *marked* (safe) - which will not
>> succeed for module memory in this case.
>> 
>> In this setting, the reasons to have -safe compiler switch are not so
>> important, they are more like convenience, meaning more like
>> -forcesafe. You would want to use this flag only when you *need* to
>> make sure your application is safe, usually when you are using other
>> libraries. By this switch you can prevent compilation of unsafe
>> application in case some other library silently changes safe module
>> to unsafe in newer version.
>> 
> Doesn't work. There are system modules which CANNOT safely be called
> from safe modules -- eg extern(C) functions. They MUST have unsafe
> interfaces.
> 

then they are not (system) modules. they are just modules with no specification.

When not using -safe switch, you cannot call from (safe) to module with no 
safety specification (you can only call (safe) and (system))

When using -safe switch, there does not exists module with not safety specification, 
all plain modules will be marked (safe), and (system) modules are unchanged. 
You will not be able to call extern(C) functions from (safe) module, because 
module in which they are defined will be marked (safe), and will not compile 
itself. There is the problem I think you are referring to: (system) modules 
should not be affected by -safe flag. User of module believes (system) is 
safe, so the (system) module can call anything anytime. So I would suggest 
such update:

when -safe switch is not used:
module name;            // interface: unsafe impl: unsafe 
module (system) name;   // interface: safe   impl: unsafe 
module (safe) name;     // interface: safe   impl: safe

when -safe switch is used:
module name;            // interface: unsafe impl: unsafe   -- when imported 
from system module
module name;            // interface: safe   impl: safe     -- when imported 
from safe modules
module (system) name;   // interface: safe   impl: unsafe 
module (safe) name;     // interface: safe   impl: safe

this means, that when -safe switch is used, that modules with no specification 
would be marked (safe) only when imported by modules marked as (safe). When 
they are imported from (system) modules, they will not be marked (safe). 
There is no need to another check if both (safe) and (system) nodules imports 
given module, because import from (safe) modules is stronger check, which 
is always fulfils by import from (system module).

In other words, (system) module does not need to perform any more checking 
when -safe flag is used, it is same as if it not used.





More information about the Digitalmars-d mailing list