October 21, 2010
Leandro Lucarella schrieb:
> Iain Buclaw, el 21 de octubre a las 11:54 me escribiste:
>> A few standard library functions, such as 'abort' and 'exit', cannot return.
>> However there is no way in DMD to let the compiler know about this.
>> Currently in D2, you must either have a 'return' or 'assert(0)' statement at
>> the end of a function body. It would be nice however if you can give hints to
>> the compiler to let it know that a function is never going to return.
>>
>> Example:
>>
>> @noreturn void fatal()
>> {
>>     print("Error");
>>     exit(1);
>> }
>>
>> The 'noreturn' keyword would tell the compiler that 'fatal' cannot return, and
>> can then optimise without regard to what would happen if 'fatal' ever did
>> return. This should also allow fatal to be used instead of a return or assert
>> statement.
>>
>> Example:
>>
>> int mycheck(int x)
>> {
>>     if (x > 1)
>>         return OK;
>>     fatal();
>> }
>>
>>
>> Thoughts?
> 
> You want to include in the language what you can do (or at least could)
> do in GDC using:
> 
> pragma(GNU_attribute, noreturn)) void fatal()
> {
>      print("Error");
>      exit(1);
> }
> 
> ?
> 

Obviously he wants a portable way to do this that will work on any up-to-date D2 compiler.. doesn't make much sense to have a gdc-only solution that makes code incompatible with dmd (and possibly other compilers). Of course one may use version(GDC) or something like that to ensure compatibility, but that's just ugly.

Cheers,
- Daniel
October 21, 2010
== Quote from Leandro Lucarella (luca@llucax.com.ar)'s article
> Iain Buclaw, el 21 de octubre a las 11:54 me escribiste:
> > A few standard library functions, such as 'abort' and 'exit', cannot return. However there is no way in DMD to let the compiler know about this. Currently in D2, you must either have a 'return' or 'assert(0)' statement at the end of a function body. It would be nice however if you can give hints to the compiler to let it know that a function is never going to return.
> >
> > Example:
> >
> > @noreturn void fatal()
> > {
> >     print("Error");
> >     exit(1);
> > }
> >
> > The 'noreturn' keyword would tell the compiler that 'fatal' cannot return, and can then optimise without regard to what would happen if 'fatal' ever did return. This should also allow fatal to be used instead of a return or assert statement.
> >
> > Example:
> >
> > int mycheck(int x)
> > {
> >     if (x > 1)
> >         return OK;
> >     fatal();
> > }
> >
> >
> > Thoughts?
> You want to include in the language what you can do (or at least could)
> do in GDC using:
> pragma(GNU_attribute, noreturn)) void fatal()
> {
>      print("Error");
>      exit(1);
> }
> ?

No.

More to the truth, when merging the 2.031 frontend, I found myself having to put in a lot of assert(0) or returns to satisfy several build errors in the EH unwind code for Dwarf2. Just seemed like a lot of redundant code to me really. Asked in #d how useful such a property would be, then I got heckled to post here.
October 21, 2010
== Quote from Daniel Gibson (metalcaedes@gmail.com)'s article
> Leandro Lucarella schrieb:
> > Iain Buclaw, el 21 de octubre a las 11:54 me escribiste:
> >> A few standard library functions, such as 'abort' and 'exit', cannot return. However there is no way in DMD to let the compiler know about this. Currently in D2, you must either have a 'return' or 'assert(0)' statement at the end of a function body. It would be nice however if you can give hints to the compiler to let it know that a function is never going to return.
> >>
> >> Example:
> >>
> >> @noreturn void fatal()
> >> {
> >>     print("Error");
> >>     exit(1);
> >> }
> >>
> >> The 'noreturn' keyword would tell the compiler that 'fatal' cannot return, and can then optimise without regard to what would happen if 'fatal' ever did return. This should also allow fatal to be used instead of a return or assert statement.
> >>
> >> Example:
> >>
> >> int mycheck(int x)
> >> {
> >>     if (x > 1)
> >>         return OK;
> >>     fatal();
> >> }
> >>
> >>
> >> Thoughts?
> >
> > You want to include in the language what you can do (or at least could)
> > do in GDC using:
> >
> > pragma(GNU_attribute, noreturn)) void fatal()
> > {
> >      print("Error");
> >      exit(1);
> > }
> >
> > ?
> >
> Obviously he wants a portable way to do this that will work on any up-to-date D2
compiler.. doesn't
> make much sense to have a gdc-only solution that makes code incompatible with
dmd (and possibly
> other compilers). Of course one may use version(GDC) or something like that to
ensure compatibility,
> but that's just ugly.
> Cheers,
> - Daniel

The GNU_attribute pragmas are just hints to the GCC backend; very limited in what they do; don't really thrive very well in D's environment.

Take for example:

pragma (GNU_attribute, vector_size(16)) typedef int MyInt;

And you have a MyInt data type that is 16bytes wide, but D will still report that
it is 4, and you can't use or assign anything to it either (else we'll ICE). I
guess it is a WIP feature that got left behind, I could have a look at it
improving it sometime, but I haven't really seen any benefits in reviving it though...
October 21, 2010
Ezneh:

> I saw something that can be good too about returned values in Nimrod :
> http://force7.de/nimrod/tut1.html#discard-statement
> Hope the explanation is sufficient. This way, the programmer knows when he "throws away" a returned value.
> I think that could be great too.

In C-like languages I've sometimes seen a cast to void (at the call point) of the return value:

cast(void)someFunction();

This silences the lint in some situations.

GNU C has the warn_unused_result that works in a different way, it makes the compiler generate a warning at the call point if you don't use the result of a function that has such attribute:
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bwarn_005funused_005fresult_007d-attribute-2509

(Some of those attributes will probably be added to D2 as non-standard extensions if they don't become standard features first.)

Bye,
bearophile
October 21, 2010
On 10/21/2010 05:54, Iain Buclaw wrote:
> @noreturn void fatal()
> {
>     print("Error");
>     exit(1);
> }

> Thoughts?

This looks wrong to me.  'fatal' returns type 'void', except that it doesn't.  I would prefer this:

null_type fatal()
{
    print("Error");
    exit(1);
}

Here 'null_type' is a type that has no values, as opposed to 'void' which has only one possible value.  No variables may be declared of type 'null_type'.  A function with a return type of 'null_type' never returns.

Either way would work (and this feature is definitely useful), but
'null_type' has some significant advantages:
  - It can be used in delegates and function pointers.
  - It can be used in generic code where you don't know if a function
will return or not.
  - It makes for more concise code.

Feel free to think of a better name than 'null_type'.


-- 
Rainer Deyke - rainerd@eldwood.com
October 21, 2010
== Quote from Rainer Deyke (rainerd@eldwood.com)'s article
> On 10/21/2010 05:54, Iain Buclaw wrote:
> > @noreturn void fatal()
> > {
> >     print("Error");
> >     exit(1);
> > }
> > Thoughts?
> This looks wrong to me.  'fatal' returns type 'void', except that it
> doesn't.  I would prefer this:
> null_type fatal()
> {
>     print("Error");
>     exit(1);
> }
> Here 'null_type' is a type that has no values, as opposed to 'void'
> which has only one possible value.  No variables may be declared of type
> 'null_type'.  A function with a return type of 'null_type' never returns.
> Either way would work (and this feature is definitely useful), but
> 'null_type' has some significant advantages:
>   - It can be used in delegates and function pointers.
>   - It can be used in generic code where you don't know if a function
> will return or not.
>   - It makes for more concise code.
> Feel free to think of a better name than 'null_type'.

Not sure what you mean when you say that void has only one possible value. To me, 'void' for a function means something that does not return any value (or result). Are you perhaps confusing it with to, lets say an 'int' function that is marked as noreturn?

Regards
Iain
October 21, 2010
On 10/21/10 12:21 CDT, Rainer Deyke wrote:
> Feel free to think of a better name than 'null_type'.

It's a theory classic called "none" or "bottom". It's the bottom of the subtyping lattice, the subtype of all possible types, a type that can never be instantiated.

The feature is nice to have but is rarely of use and hardly a game changer.


Andrei
October 21, 2010
Daniel Gibson, el 21 de octubre a las 17:15 me escribiste:
> >You want to include in the language what you can do (or at least could)
> >do in GDC using:
> >
> >pragma(GNU_attribute, noreturn)) void fatal()
> >{
> >     print("Error");
> >     exit(1);
> >}
> >
> >?
> >
> 
> Obviously he wants a portable way to do this that will work on any up-to-date D2 compiler.. doesn't make much sense to have a gdc-only solution that makes code incompatible with dmd (and possibly other compilers). Of course one may use version(GDC) or something like that to ensure compatibility, but that's just ugly.

Maybe it came out wrong, it wasn't my intention to make it sound like a bad idea. On the contrary, I think is a good idea, and there are plenty of other GCC attributes that worth having.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
PIRATAS DEL ASFALTO ROBAN CAMION CON POLLOS CONGELADOS...
	-- Crónica TV
October 21, 2010
"Iain Buclaw" <ibuclaw@ubuntu.com> wrote in message news:i9p9li$282u$1@digitalmars.com...
>A few standard library functions, such as 'abort' and 'exit', cannot return.
> However there is no way in DMD to let the compiler know about this.
> Currently in D2, you must either have a 'return' or 'assert(0)' statement
> at
> the end of a function body. It would be nice however if you can give hints
> to
> the compiler to let it know that a function is never going to return.
>
> Example:
>
> @noreturn void fatal()
> {
>    print("Error");
>    exit(1);
> }
>
> The 'noreturn' keyword would tell the compiler that 'fatal' cannot return,
> and
> can then optimise without regard to what would happen if 'fatal' ever did
> return. This should also allow fatal to be used instead of a return or
> assert
> statement.
>
> Example:
>
> int mycheck(int x)
> {
>    if (x > 1)
>        return OK;
>    fatal();
> }
>
>
> Thoughts?

A while ago someone mentioned a feature that some languages have that's a specific that indicates "never returns". (I'll just call it type "noreturn").

One of the nice things about that is you don't have to provide a "fake" return type. For instance, with your "@noreturn": "@noreturn int foo()" would be legal, but wouldn't make any sence. And in a way, even "@noreturn void foo()" isn't great since a "void" return value suggests that it at least returns.

So your "fatal" would be like this:

noreturn fatal()
{
   print("Error");
   exit(1);
}

And likewise, "exit" would be declared as "noreturn exit(int)" (otherwise the compiler would, presumably, complain that a "noreturn" function returns).

Since this "noreturn" would be an actual type, in the langauges that have it, it will often participate in arithmetic types, so you can have a function that may or may not return:

Arithmetic!(noreturn, int) foo(int num)
{
    if(num == 7)
        exit(1);
    else
        return num;
}

Or something like that anyway. (Although, AIUI, those languages generally have arithmetic types built into the langauge itself.)


October 21, 2010
Nick Sabalausky:

> One of the nice things about that is you don't have to provide a "fake" return type. For instance, with your "@noreturn": "@noreturn int foo()" would be legal, but wouldn't make any sence. And in a way, even "@noreturn void foo()" isn't great since a "void" return value suggests that it at least returns.

I suggest to keep things simpler, minimize changes to other parts of D, and avoid creating new keywords for this very minor feature, and allow only the signature:
@noreturn void somefunctioname(...)

So this is an additive change to D2, and may be added later.

Bye,
bearophile