all OS functions should be "nothrow @trusted @nogc"

Moritz Maxeiner via Digitalmars-d digitalmars-d at puremagic.com
Tue Jul 25 08:29:55 PDT 2017


On Tuesday, 25 July 2017 at 14:39:15 UTC, Shachar Shemesh wrote:
> On 25/07/17 17:24, Moritz Maxeiner wrote:
>> On Tuesday, 25 July 2017 at 13:50:16 UTC, Shachar Shemesh 
>> wrote:
>>> The title really does says it all.
>> 
>> Since you explicitly state *all* OS functions:
>> nothrow: Should be OK (only callbacks could violate this and 
>> they should be nothrow, anyway).
> Technically, any system call that is a pthreads cancellation 
> point may throw a C++ exception.

Good to know, then since D is supposed to be able to catch C++ 
exceptions (and can on 64bit Linux [1]) none of those may be 
attributed as `nothrow`, because C++ exceptions don't derive from 
`Error`.

>
> If we go down that route, however, calling system calls from 
> nothrow becomes completely impossible, which is another way of 
> saying that decorating just about anything with nothrow becomes 
> impossible.

No. `nothrow` functions can call throwing ones, as long as they 
catch any exceptions not derived from Error thrown by them.

>
>> @trusted: This can only be done for those functions that don't 
>> take arguments open to memory corruption. Take a look at POSIX 
>> read, it can never be trusted (same as any C function taking 
>> pointer+length of pointed to).
>> @nogc: This can only be done for those functions that are 
>> statically known to never call a D callback that's not also 
>> @nogc. Take a look at pthread_create vor pthread_join, they 
>> can never be @nogc, because that would mean threads may never 
>> allocate with the GC.
>
> The decoration's situation with callbacks is pretty horrible 
> throughout D.

Do you mean throughout druntime and phobos?

> I'm not sure this is the most compelling argument, however. The 
> function passed to pthread_create does not, logically, run in 
> the pthread_create function. As such, I don't think this logic 
> holds.

Then the @nogc definition would need to be updated from: "or 
indirectly through functions it may call" to reflect this, 
because that can be interpreted both ways.

>
> As for pthread_join, I have no idea what you meant by it. 
> Please elaborate why you think it is a problem.

Possible scenario on single core (no hyperthreading) system:
- thread 1 spawns thread 2
- thread 1 enters @nogc function `foo` and calls `pthread_join` 
on thread 2 before its own timeslice is over (and thus enters 
blocked state)
- thread 2 does work allocating via the GC, then terminates
- thread 1 wakes up and leaves @nogc function `foo`

Because @nogc (in contrast to nothrow) is explicitly designed as 
transitive, logically speaking, `foo` violated its @nogc 
constraint (it *caused* the GC allocations in thread 2).

>
>> 
>> ---
>> auto result = () @trusted { return systemFunction(...) }();
>> ---
>
> Care to explain how to adapt that neat trick for "nothrow" and 
> "@nogc"?

nothrow: assumeWontThrow [2]
@nogc: assumeNoGC [3]

[1] http://forum.dlang.org/thread/n7jorc$1ied$1@digitalmars.com
[2] https://dlang.org/library/std/exception/assume_wont_throw.html
[3] https://p0nce.github.io/d-idioms/#Bypassing-@nogc


More information about the Digitalmars-d mailing list