November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu wrote:
> Walter Bright wrote:
>> Andrei Alexandrescu wrote:
>>> Walter Bright wrote:
>>>> Jason House wrote:
>>>>> I posted in the other thread how casting to immutable/shared can be
>>>>> just as bad. A leaked reference prior to casting to immutable/shared
>>>>> is in effect the same as casting away shared. No matter how you mix
>>>>> thread local and shared, or mutable and immutable, you still have the
>>>>> same undefined behavior
>>>>
>>>> Not undefined, it's just that the compiler can't prove it's defined behavior. Hence, such code would go into a trusted function.
>>>
>>> Are we in agreement that @safe functions have bounds checking on regardless of -release?
>>
>> You're right from a theoretical perspective, but not from a practical one. People ought to be able to flip on 'safe' without large performance penalties.
>>
>> If it came with inescapable large performance penalties, then it'll get a bad rap and people will be reluctant to use it, defeating its purpose.
>
> This is a showstopper.
>
> What kind of reputation do you think D would achieve if "safe" code has buffer overrun attacks?
>
> A function that wants to rely on hand-made verification in lieu of bounds checks may go with @trusted. There is absolutely no way a @safe function could allow buffer overruns in D, ever.
I agree if the flag is called "-release". But if the "disable bounds checking" flag is renamed to -unsafe or similar, I can't see any impact on reputation.
|
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | On Fri, Nov 6, 2009 at 12:48 AM, Don <nospam@nospam.com> wrote:
> Walter Bright wrote:
>>
>> Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman.
>>
>> Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior. Implementation defined behavior (such as varying pointer sizes) is still allowed.
>>
>> Memory safety is a subset of this. Undefined behavior nicely covers things like casting away const and shared.
>>
>> Safety has a lot in common with function purity, which is set by an attribute and verified by the compiler. Purity is a subset of safety.
>>
>> Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:
>>
>> @safe
>> @trusted
>>
>> A function marked as @safe cannot use any construct that could result in undefined behavior. An @safe function can only call other @safe functions or @trusted functions.
>>
>> A function marked as @trusted is assumed to be safe by the compiler, but is not checked. It can call any function.
>
>>
>> Functions not marked as @safe or @trusted can call any function.
>>
>> To mark an entire module as safe, add the line:
>>
>> @safe:
>>
>> after the module statement. Ditto for marking the whole module as @trusted. An entire application can be checked for safety by making main() safe:
>>
>> @safe int main() { ... }
>>
>> This proposal eliminates the need for command line switches, and versioning based on safety.
>
> I think it's important to also have @unsafe. These are functions which are
> unsafe, and not trusted. Like free(), for example. They're usually easy to
> identify, and should be small in number.
> They should only be callable from @trusted functions.
> That's different from unmarked functions, which generally just haven't been
> checked for safety.
> I want to able to find the cases where I'm calling those guys, without
> having to mark every function in the program with an @safe attribute.
Agreed. Having @safe but no @unsafe is like having "private:" with no "public:".
--bb
|
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | > I agree if the flag is called "-release". But if the "disable bounds
> checking" flag is renamed to -unsafe or similar, I can't see any
> impact on reputation.
Ditto.
|
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Hello Andrei,
> Walter Bright wrote:
>
>> Jason House wrote:
>>
>>> I posted in the other thread how casting to immutable/shared can be
>>> just as bad. A leaked reference prior to casting to immutable/shared
>>> is in effect the same as casting away shared. No matter how you mix
>>> thread local and shared, or mutable and immutable, you still have
>>> the same undefined behavior
>>>
>> Not undefined, it's just that the compiler can't prove it's defined
>> behavior. Hence, such code would go into a trusted function.
>>
> Are we in agreement that @safe functions have bounds checking on
> regardless of -release?
>
> Andrei
>
I think there are two cases:
User would want max performance from a some library, but he does not care about performance. User should have the right to override intentions of library writer, making his code less safe, to achieve speed. Compiler flag -unsafe (or -unsafe-no-bounds-checking) should do this. The user will know that he is *overriding* the original safety to lower level.
Also, when a library writer wants his code to appeal and be usable to most users, he should mark it @safe or @trusted. But in situation, when he knows that safe code would be always bounds-checked (there is no -unsafe compiler switch), he may rather mark his code @trusted, even if it would be safe, in order to appeal to user that don't want slow (bounds-checked) library. If the library writer knows that users can override safety (bounds-checking), he would not hesitate to use @safe where appropriate.
the -unsafe-no-bounds-checking flag is essential for properly working of safeness in D.
|
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | Leandro Lucarella wrote:
> Michel Fortin, el 5 de noviembre a las 19:43 me escribiste:
>> On 2009-11-05 19:14:47 -0500, Walter Bright <newshound1@digitalmars.com> said:
>>
>>> Andrei Alexandrescu wrote:
>>>> Are we in agreement that @safe functions have bounds checking on
>>>> regardless of -release?
>>> You're right from a theoretical perspective, but not from a
>>> practical one. People ought to be able to flip on 'safe' without
>>> large performance penalties.
>>>
>>> If it came with inescapable large performance penalties, then
>>> it'll get a bad rap and people will be reluctant to use it,
>>> defeating its purpose.
>> But if you remove bound checking, it isn't safe anymore, is it?
>
> 100% safe doesn't exist. If you think you have it because of
> bound-checking, you are wrong.
>
>> Sometime safety is more important than performance. If I needed
>> performance in a safe program, I'd profile and find the bottlenecks,
>> review carefully those parts of the code slowing down the program,
>> then when I trust them perfectly I'd add the @trusted attribute.
>> @trusted should remove bound checks (in release mode). @safe should
>> keep them to keep other less trustworthy pieces of of the program
>> truly safe.
>
> What if I'm using an external library that I don't control? *That's* the
> problem for me, I want to be able to compile things I *trust* as if they
> were *trusted* :)
>
>> That said, I'd be in favor of a compiler switch to enable/disable
>> runtime checks in release mode... perhaps "-safe" could return as
>> way to generate truly safe binaries even in release mode. This would
>> also make it pretty easy to evaluate how much impact those runtime
>> checks have on final executable (by turning on and off the compiler
>> switch).
>
> I vote for an -unsafe (and/or -disable-bound-check). Safe should be the
> default.
>
Doesn't safe disable features? Like taking the adress of things on the stack?
If I am not mistaken and this is the case, I vote against default safe. It's not a big problem for bigger projects that actually need safety, and it doesn't mess up any quick-and-dirty code.
|
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | == Quote from Don (nospam@nospam.com)'s article
> Walter Bright wrote:
> > Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman.
> >
> > Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior. Implementation defined behavior (such as varying pointer sizes) is still allowed.
> >
> > Memory safety is a subset of this. Undefined behavior nicely covers things like casting away const and shared.
> >
> > Safety has a lot in common with function purity, which is set by an attribute and verified by the compiler. Purity is a subset of safety.
> >
> > Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:
> >
> > @safe
> > @trusted
> >
> > A function marked as @safe cannot use any construct that could result in undefined behavior. An @safe function can only call other @safe functions or @trusted functions.
> >
> > A function marked as @trusted is assumed to be safe by the compiler, but is not checked. It can call any function.
> >
> > Functions not marked as @safe or @trusted can call any function.
> >
> > To mark an entire module as safe, add the line:
> >
> > @safe:
> >
> > after the module statement. Ditto for marking the whole module as @trusted. An entire application can be checked for safety by making main() safe:
> >
> > @safe int main() { ... }
> >
> > This proposal eliminates the need for command line switches, and versioning based on safety.
> I think it's important to also have @unsafe. These are functions which
> are unsafe, and not trusted. Like free(), for example. They're usually
> easy to identify, and should be small in number.
> They should only be callable from @trusted functions.
> That's different from unmarked functions, which generally just haven't
> been checked for safety.
> I want to able to find the cases where I'm calling those guys, without
> having to mark every function in the program with an @safe attribute.
Can't you just mark every *module* in the program with the @safe attribute?
|
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Instead of just defining @safe and @trusted it should possible to define this type of code annotations and constrains in D. See Red Code/Green Code - Generalizing Const by Scott Meyers http://video.google.com/videoplay?docid=-4728145737208991310# Then we can define @safe, @pure, @thread_safe, @exception_safe, @gpl, @lgpl, @beautiful and @ugly code or all the constrains we like. It would also be nice if we could annotate code with @debug and then it would argument the code with debugging code. Walter Bright wrote: > Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman. > > Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior. Implementation defined behavior (such as varying pointer sizes) is still allowed. > > Memory safety is a subset of this. Undefined behavior nicely covers things like casting away const and shared. > > Safety has a lot in common with function purity, which is set by an attribute and verified by the compiler. Purity is a subset of safety. > > Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes: > > @safe > @trusted > > A function marked as @safe cannot use any construct that could result in undefined behavior. An @safe function can only call other @safe functions or @trusted functions. > > A function marked as @trusted is assumed to be safe by the compiler, but is not checked. It can call any function. > > Functions not marked as @safe or @trusted can call any function. > > To mark an entire module as safe, add the line: > > @safe: > > after the module statement. Ditto for marking the whole module as @trusted. An entire application can be checked for safety by making main() safe: > > @safe int main() { ... } > > This proposal eliminates the need for command line switches, and versioning based on safety. -- Join me on CrowdNews http://crowdnews.eu/users/addGuide/42/ Facebook http://www.facebook.com/profile.php?id=1198821880 Linkedin http://www.linkedin.com/pub/0/117/a54 Mandala http://www.mandala.dk/view-profile.php4?profileID=7660 |
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yigal Chripun | Yigal Chripun wrote: > On 05/11/2009 23:45, grauzone wrote: >> Ary Borenszweig wrote: >>> grauzone wrote: >>>> Frank Benoit wrote: >>>>> safe should be the default. The unsafe part should take the extra >>>>> typing, not the other way. Make the user prefer the safe way. >>>> >>>> No. D is not C#. >>> >>> D is an unsafe language. >>> C# is a safe language. >>> >>> Like that? :) >> >> If you mean memory safety, then yes and will probably forever be for all >> practical uses (unless D gets implemented on a Java or .net like VM). > > C# does allow memory unsafe code inside unsafe blocks. There's an alloca and malloca functions for allocating on the stack. > > VM is just an abstract (virtual) instruction set. You can design a safe native one or an unsafe virtual one. it's all a matter of design choices. there's nothing magical about a VM that makes it inherently safe. Yes, but most VMs are designed to be memory safe for some reason, and I trust an instruction set designed to be memory safe more than having an additional "safety" feature tucked onto a complex language like D, and its half-assed implementation in dmd. > IMO D should be safe by default and allow unsafe code when it is appropriately marked as such, regardless of a VM. I think most D code will have to be somewhat "unsafe" to be efficient, or to do stuff like binding to C libs. I already can see how code will be scattered with "@safe", "@trusted", etc., making that whole "safety" promise both a joke (theoretically) and a major PITA for the programmer (practically). But it's pointless to discuss about this, because SafeD is not here yet. > BTW, so called native code on Intel processors runs in a VM as well. > Intel's cisc instruction set is translated to a risc like micro-ops and those micro-ops are executed. the only difference is that this is done in hardware by the processor. > If you water down the word "VM" that much, it doesn't mean anything anymore. |
November 06, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to Knud Soerensen | == Quote from Knud Soerensen (4tuu4k002@sneakemail.com)'s article
> Instead of just defining @safe and @trusted
> it should possible to define this type of code annotations and
> constrains in D.
> See Red Code/Green Code - Generalizing Const by Scott Meyers
> http://video.google.com/videoplay?docid=-4728145737208991310#
> Then we can define @safe, @pure, @thread_safe, @exception_safe, @gpl,
> @lgpl, @beautiful and @ugly code or all the constrains we like.
> It would also be nice if we could annotate code with @debug
> and then it would argument the code with debugging code.
> Walter Bright wrote:
> > Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman.
I'll watch that video tomorrow, (or not it is a bit long.) :-)
attrib(nogc)
void handleSituation1()
{
int * m =casting malloc(20);
}
attrib(nogc)
void handleSituation1() requires(nogc)
{
handleSituation2();
}
void helloWorld()
{
requires(nogc)
{
handleSituation2();
}
}
attrib(validatedBy("Tom hank"))
void doStuff3() requires(validatedBy)
{
callThis();
callThat();
}
attrib(trusted) void handleSituation() requires(nogc) permit(unsafe)
{
}
void handleSituation() permit(unsafe)
{
}
void handleSituation()
{
...
permit(unsafe)
{
}
}
----mutable isolation = mutiso
requires(pure)
class BoeClass
{
private:
int number;
public:
prop int Number
{
return number;
}
{
number = value;
}
int dupsy()
{
return number + 1;
}
}
requires(pure) int doStuff( int a)
{
BoeClass jim;
}
--------
void doStuff() //attrib(safe) requires(safe)
attrib(safe) void doStuff() requires(safe) //default
void doStuff() permit(!safe) //loses the safe attribute
requires(safe) void doStuff() //enforces and attributes it.
requires(nogc) void doStuff() //enforces and attributes it.
void doStuff() requires(nogc) //enforces but does not attribute it.
attrib(validated) doStuff() permit(!safe) //validated by the programmer using
unsafe code
attrib(default) void doStuff() requires( default - [safe] )
Okay I'm going nuts again.
-----------------
Okay for let's say "properties" that are meant to be serialized. By which I mean "actual data", could we start them with a capital case. This would tell other programmers which ones to pick. Bad idea?
struct Area
{
int Width() //Big letters
{
return width;
}
int Height() //Big letters
{
return height;
}
int area() //small letters
{
return width * height;
}
}
|
November 07, 2009 Re: Safety, undefined behavior, @safe, @trusted | ||||
---|---|---|---|---|
| ||||
Posted in reply to grauzone | grauzone wrote:
> If you mean memory safety, then yes and will probably forever be for all practical uses (unless D gets implemented on a Java or .net like VM).
A VM is neither necessary nor sufficient to make a language memory safe. It's all in the semantics of the language.
|
Copyright © 1999-2021 by the D Language Foundation