proposed @noreturn attribute

Nicholas Wilson via Digitalmars-d digitalmars-d at puremagic.com
Sun Jul 9 21:02:59 PDT 2017


On Monday, 10 July 2017 at 03:25:26 UTC, Nick Sabalausky 
(Abscissa) wrote:
> On 07/09/2017 05:14 PM, H. S. Teoh via Digitalmars-d wrote:
>> On Sun, Jul 09, 2017 at 02:01:08PM -0400, Andrei Alexandrescu 
>> via Digitalmars-d wrote:
>>> On 07/09/2017 12:19 PM, Steven Schveighoffer wrote:
>>>> It's no more of a hack than leaving assert(0) in release 
>>>> code.
>>>
>>> I wouldn't argue that. I do argue it's a hack compared to the
>>> principled solution of a bottom type. -- Andrei
>> 
>> I like out{ assert(0); } for pretty much the same reasons as 
>> Steven
>> lists. The biggest pro is that **the language already supports 
>> it*.
>> Contract syntax already is meant to signal intent, and 
>> assert(0) signals
>> "never gets here". You can't find a better solution than this. 
>> All the
>> other alternatives require adding even more baggage to an 
>> already
>> heavy language, or compiler voodoo to recognize a particular 
>> pattern of
>> defining a type.  I'd say out{assert(0);} is the principled 
>> solution --
>> expressing something the current language can already express, 
>> and it's
>> the other alternatives that are "exotic".
>> 
>
> Prioritizing "path of least resistense" over "this is cleaner 
> and more principled" is the hallmark of C++-style langauge 
> design. Please, please, please, let's stay away from that path.

While I agree with your sentiment in principle (heh), we need to 
keep in mind it purpose.
So far I count four requirements of a solution:
     documentation
     optimisation
     ability to statically reflect upon
     ability to implement

Of the approached listed only out{assert(0);} fails the static 
reflection check.
Which leaves
1)@noreturn
2)@disable(return)
3)none

1 & 2 are almost functionally identical in their implementation 
with 2 requiring some semantic hacks to the compiler and 
precludes the AliasSeq approach below, so I consider 1 to be 
superior to 2.

this leaves 1 & 3.

w.r.t documentation for 1 this is a solved problem, it becomes 
part of the type signature and will be picked up in the 
documentation building tools. 3 it becomes part of the return 
type and can also be solved by documenting the type.

w.r.t optimisation assuming both 1 & 3  impact DMD equally then 
there is no difference except that:

Implementation: 3 would require GDC and LDC to make changes _when 
they already have a solution_. It would also be _considerably 
more work_ than 1, and would be _backwards incompatible_ with 
older compilers. In fact 1 could be implemented _Immediately_ for 
GDC and LDC by having

enum __noreturn;
version (DigitalMars) alias noreturn = __noreturn;
else version(GNU) {
     import gcc.attributes : attribute;
     alias noreturn = AliasSeq!(__noreturn,attribute("noreturn"));
}
else version (LDC)
{
     import ldc.attributes : llvmAttr;
     alias noreturn = AliasSeq!(__noreturn,llvmAttr("noreturn"));
}

and reflect upon the presence of __noreturn;

I am strongly against the need to complicate the compiler when an 
equal (IMHO better) solution _already exists_, for extremely 
marginal gain: anyone seriously concerned about the small 
optimisation benefit will already be using GDC or LDC, the 
applicability of noreturn is minuscule, AFAICT C's _exit and an 
unconditional throw (Exception or Error) are the only functions 
for which it applies.


More information about the Digitalmars-d mailing list