noreturn

K

Keith Thompson

Ralph Spitzner said:
Keith Thompson wrote:
[...]
The meaning of 'return' isn't a matter of perception.

Are you arguing that the use of `_Noreturn` in my example is incorrect,
or that it should mean something other than what the standard says it
means?
No, not arguing about the _Noreturn statement itself (which might be
making things easier for the optimizer), but rather about that a
function must end somehow, be it by a kill -9.
Unless you're running on bare metal something will catch that
termination and clean up,therefore having noticed a 'return' :p

Maybe that noreturn statement is just a little bit too abstract,
or the term is just strange to me.

The compiler could just grok it by seeing something like
for(;;)
or
while(1)

If you want to discuss something other than "noreturn", perhaps you
could make it clearer that you're not talking about "noreturn". Your
initial followup in this thread sounded very much like you were
disagreeing with what "noreturn" means.

If you'd like to understand what "noreturn" means, grab a copy of
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf and search for
"noreturn" (including references to the "_Noreturn" keyword).

One potentially tricky aspect is that any use of the word "shall" that's
not within a constraint means that violating the requirement causes
undefined behavior. For example, if I write:

#include <stdio.h>
#include <stdnoreturn.h>

noreturn int foo(void) {
return 42;
}

int main(void) {
int result = foo();
printf("result = %d\n", result);
return 0;
}

the compiler is not required to diagnose the error -- but neither is it
required to generate any code for the printf() call. (And with gcc, it
can produce no output or crash with a segmentation fault, depending on
the optimization level).
 
N

Nobody

AIUI, setjmp() always returns at least once--and sometimes more than once.

Indeed. If it returns a non-zero value (i.e. due to longjmp()), it isn't
really "returning to its caller".

I suppose that fork() belongs in the same boat.
I'm not familiar with that one.

Advanced version of setjmp/longjmp, providing cooperative multi-threading.
Calling swapcontext() typically results in a return from some previous
call to swapcontext(); some later swapcontext() call might result in a
return from the current one. swapcontext() can often be emulated via a
combination of setjmp(), longjmp(), and (non-portable) manipulation of the
jmp_buf.

It has been removed from the latest revision of POSIX, probably because
trying to specify interactions between swapcontext() and pthreads was too
much of a headache.
 
L

Lew Pitcher

Indeed. If it returns a non-zero value (i.e. due to longjmp()), it isn't
really "returning to its caller".

I suppose that fork() belongs in the same boat.

ITYM execlp() and friends

fork() always returns to the caller
 
J

Joe Pfeiffer

Ralph Spitzner said:
Keith Thompson wrote:
[...]
The meaning of 'return' isn't a matter of perception.

Are you arguing that the use of `_Noreturn` in my example is incorrect,
or that it should mean something other than what the standard says it
means?
No, not arguing about the _Noreturn statement itself (which might be
making things easier for the optimizer), but rather about that a
function must end somehow, be it by a kill -9.
Unless you're running on bare metal something will catch that
termination and clean up,therefore having noticed a 'return' :p

You're using a decidedly idiosyncratic definition of "return".
Maybe that noreturn statement is just a little bit too abstract,
or the term is just strange to me.

The compiler could just grok it by seeing something like
for(;;)
or
while(1)

While there are cases in which the compiler could recognize a function
never returns, and there are cases in which it could recognize the
function always has to return, it was proved decades ago that there are
cases in which the compiler can't be sure.
 
S

Stephen Sprunk

Most running C programs never return to anything - either in main() or a
subfunction of main() there is an infinite loop that never exits.

Or were you only thinking of PC-style programs running on desktops, and
forgetting about embedded systems - which generally do not stop, and for
which the space savings allowed by "noreturn" are particularly relevant?

Even "PC-style programs running on desktops" exhibit the same pattern,
since modern GUI toolkits contain the same infinite loop, parsing
messages/events. If they do terminate, it is via some other means, eg.
exit(), rather than returning from main(). However, it's doubtful that
marking such functions "noreturn" would provide much, if any, savings
considering the overall size.

S
 
S

Stephen Sprunk

Indeed. If it returns a non-zero value (i.e. due to longjmp()), it isn't
really "returning to its caller".

Well, that depends on how creative you are in defining "caller".
Execution returns to setjmp()'s caller rather than longjmp()'s caller.
The problem is that setjmp() had previously returned to its caller, so
the meaning of "returning" to that caller _again_ is non-obvious, and
some might say that's not really "returning" at all since you can't have
a return without a call.
I suppose that fork() belongs in the same boat.

fork() always returns to its caller--and usually twice.

S
 
R

Ralph Spitzner

Keith Thompson wrote:
[...]
the compiler is not required to diagnose the error -- but neither is it
required to generate any code for the printf() call. (And with gcc, it
can produce no output or crash with a segmentation fault, depending on
the optimization level).

Ok, got it now, sorry Willem too, didn't mean to offend.
Maybe I'm just getting old, not seeing advantages of
this or that keyword/qualifier :)
-rasp
 
R

Ralph Spitzner

David Brown wrote:
[...]
But on PC-sized programs, the space savings are pretty much irrelevant -
the main uses of "noreturn" are for static error checking (it's always
useful for the compiler to get more information) and some optimisations
(for example in optimising a conditional that contains a "noreturn" call
in a branch).

Thank you for finding the words I was trying to say... :)
 
J

Jens Gustedt

Hello,

Am 20.08.2012 05:34, schrieb Joe Pfeiffer:
While there are cases in which the compiler could recognize a function
never returns, and there are cases in which it could recognize the
function always has to return, it was proved decades ago that there are
cases in which the compiler can't be sure.

There are even cases where the compiler can't know at all, namely when
it only sees the declaration but not the definition. Therefore it is a
really smart idea to allow to specify that properly in the interface :)

Jens
 
K

Keith Thompson

Ralph Spitzner said:
Keith Thompson wrote:
[...]
the compiler is not required to diagnose the error -- but neither is it
required to generate any code for the printf() call. (And with gcc, it
can produce no output or crash with a segmentation fault, depending on
the optimization level).

Ok, got it now, sorry Willem too, didn't mean to offend.
Maybe I'm just getting old, not seeing advantages of
this or that keyword/qualifier :)

In general, the advantage of such qualifiers (restrict, noreturn
-- even register) is to give more information to the compiler.
In most cases, the compiler is free to ignore that information,
but it provides an opportunity for optimization.

In many cases, the information is in the form of a promise made
by the programmer to the compiler. The compiler is free to rely
on that promise -- and if the programmer has lied (e.g., using
`noreturn` on a function that does return to its caller), then the
compiler can take bloody revenge (or, more realistically, generate
code that doesn't behave as it would in the absence of the promise).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,573
Members
47,205
Latest member
ElwoodDurh

Latest Threads

Top