January 02, 2013
On Wednesday, 2 January 2013 at 22:53:04 UTC, Jonathan M Davis wrote:
> Then we're going to have to disagree, and I believe that Walter and Andrei are
> completely with me on this one. If all of the constructs that you use are
> @safe, then it should be _guaranteed_ that your program is memory-safe. That's
> what @safe is for. Yes, it can be gotten around if the programmer marks
> @system code as @trusted when it's not really memory-safe, but that's the
> programmer's problem. @safe is not doing it's job and is completely pointless
> if it has any holes in it beyond programmers mislabeling functions as @trusted.
> - Jonathan M Davis

Perhaps it is worth looking at Rust for this problem? They have been looking pretty hard at the lifetimes of data/pointers and perhaps they have a (possibly partial) solution that can be used in the D compiler. It seems to me a ref in D has many things in common with Rust's borrowed pointers.
January 02, 2013
On Wed, Jan 02, 2013 at 06:30:38PM -0500, Jonathan M Davis wrote:
> On Wednesday, January 02, 2013 15:06:24 H. S. Teoh wrote:
> > All extern(C) functions must be @system by default. It makes no sense to allow a @safe extern(C) function, since there is no way for the compiler to verify anything at all. The best you can do is @trusted.
> 
> Agreed. And @trusted is seriously questionable.
[...]

We may not have a choice on that, if some Phobos code needs to call C in the backend but needs to expose a @safe interface. But yeah, if possible, we should prohibit @trusted on extern(C) functions as well.


T

-- 
Two American lawyers went down to the beach for a swim. Seeing a canoe rental nearby, one asked the other, "Roe, or Wade?"
January 02, 2013
On 1/2/13 5:21 PM, Maxim Fomin wrote:
> On Wednesday, 2 January 2013 at 19:37:51 UTC, Jonathan M Davis wrote:
>> On Wednesday, January 02, 2013 13:45:32 Maxim Fomin wrote:
>>> I think it should not be fixed, but probably compiler may issue
>>> warning at some circumstances when it can realize this situation.
>>
>> It's a hole in @safe. It must be fixed. That's not even vaguely up for
>> discussion. The question is _how_ to fix it. Ideally, it would be
>> fixed in a way
>> that limits how much more code has to become @system.
>
> I argue that @safity can be easily broken (not only by example I
> provided) and there is no way to fix all holes because D is a system
> language and provides access to low-level features. @Safe is good to
> warn about (not prevent from) doing something wrong but it cannot stop
> from all safety breakages.

That is incorrect.

Andrei
January 02, 2013
On Sunday, 30 December 2012 at 08:38:27 UTC, Jonathan M Davis wrote:
> After some recent discussions relating to auto ref and const ref, I have come
> to the conlusion that as it stands, ref is not @safe. It's @system. And I
> think that we need to take a serious look at it to see what we can do to make
> it @safe. The problem is combining code that takes ref parameters with code
> that returns by ref.

The best solution I can think of is for the @safe code to require a ref return value is treated with the same care as all the function input arguments. I'll try to annotate the example code you gave to explain.


> Take this code for example:
>
> ref int foo(ref int i)
> {
>     return i;
> }

This function is valid. Ref input arguments can be returned.


>
> ref int bar()
> {
>     int i = 7;
>     return foo(i);
> }

If @safe, this code will not compile.
Error: foo may return a local stack variable
Since "i" is a local variable, "foo(i)" might return it.


>
> ref int baz(int i)
> {
>     return foo(i);
> }

This function is fine. "i" is an input argument so "foo(i)" is considered to be equivalent to an input argument.

>
> void main()
> {
>     auto a = bar();
>     auto b = baz(5);
> }

Both function calls compile. The variable a could be returned. I'm not sure if b should be returnable by ref. if "5" is a manifest constant, it must be an error in @safe code. If it has a permanent address, it could be returned.
January 02, 2013
On Wednesday, 2 January 2013 at 23:08:14 UTC, H. S. Teoh wrote:
> All extern(C) functions must be @system by default. It makes no sense to
> allow a @safe extern(C) function, since there is no way for the compiler
> to verify anything at all. The best you can do is @trusted.

@trusted shouldn't be a part of the function signature anyway, see http://forum.dlang.org/thread/blrglebkzhrilxkbprgh@forum.dlang.org. Somebody up for creating a DIP on that?

David
January 03, 2013
On Thu, Jan 03, 2013 at 12:53:56AM +0100, David Nadlinger wrote:
> On Wednesday, 2 January 2013 at 23:08:14 UTC, H. S. Teoh wrote:
> >All extern(C) functions must be @system by default. It makes no sense to allow a @safe extern(C) function, since there is no way for the compiler to verify anything at all. The best you can do is @trusted.
> 
> @trusted shouldn't be a part of the function signature anyway, see http://forum.dlang.org/thread/blrglebkzhrilxkbprgh@forum.dlang.org. Somebody up for creating a DIP on that?
[...]

Good point, @trusted is an implementation detail that should not pollute public APIs.


T

-- 
Век живи - век учись. А дураком помрёшь.
January 03, 2013
On 01/03/2013 12:48 AM, Jason House wrote:
> ...
>
>>
>> ref int bar()
>> {
>>     int i = 7;
>>     return foo(i);
>> }
>
> If @safe, this code will not compile.
> Error: foo may return a local stack variable
> Since "i" is a local variable, "foo(i)" might return it.
>
>
>>
>> ref int baz(int i)
>> {
>>     return foo(i);
>> }
>
> This function is fine. "i" is an input argument so "foo(i)" is
> considered to be equivalent to an input argument.
>

Those two cases are pretty much the same.
January 03, 2013
On Thursday, 3 January 2013 at 00:13:41 UTC, H. S. Teoh wrote:
> On Thu, Jan 03, 2013 at 12:53:56AM +0100, David Nadlinger wrote:
>> On Wednesday, 2 January 2013 at 23:08:14 UTC, H. S. Teoh wrote:
>> >All extern(C) functions must be @system by default. It makes no sense
>> >to allow a @safe extern(C) function, since there is no way for the
>> >compiler to verify anything at all. The best you can do is @trusted.
>> 
>> @trusted shouldn't be a part of the function signature anyway, see
>> http://forum.dlang.org/thread/blrglebkzhrilxkbprgh@forum.dlang.org.
>> Somebody up for creating a DIP on that?
> [...]
>
> Good point, @trusted is an implementation detail that should not pollute
> public APIs.
>
>
> T

Reading through the discussion on the subject, I have to agree that @trusted should be used to mark implementation details and not the api.

--rt

January 03, 2013
On 01/03/13 00:06, H. S. Teoh wrote:
> All extern(C) functions must be @system by default. It makes no sense to allow a @safe extern(C) function, since there is no way for the compiler to verify anything at all. The best you can do is @trusted.

extern(C) does not imply extern.

And for extern functions -- @safe and @trusted are equivalent, unless this
makes a difference for name mangling, which it a) shouldn't, b) already
does not for the extern(C) case.

artur
January 03, 2013
On Thursday, 3 January 2013 at 05:56:27 UTC, Timon Gehr wrote:
> On 01/03/2013 12:48 AM, Jason House wrote:
>> ...
>>
>>>
>>> ref int bar()
>>> {
>>>    int i = 7;
>>>    return foo(i);
>>> }
>>
>> If @safe, this code will not compile.
>> Error: foo may return a local stack variable
>> Since "i" is a local variable, "foo(i)" might return it.
>>
>>
>>>
>>> ref int baz(int i)
>>> {
>>>    return foo(i);
>>> }
>>
>> This function is fine. "i" is an input argument so "foo(i)" is
>> considered to be equivalent to an input argument.
>>
>
> Those two cases are pretty much the same.

If what I suggest is done, they must be differentiated. If you replace "return foo(i)" with "return i", the compiler will already issue an error for the local variable case.