Der Header stdnoreturn.h
enthält das Funktions-Attribut noreturn
.
Unter C++ ist die Datei als cstdnoreturn
einzubinden.
stdnoreturn
ist ab C11 Teil des Standards. Für ältere Compiler (z.B. GCC vor Version 4.7) muss die C11-Unterstützung explizit aktiviert werden:
$ gcc -o main main.c -std=c11
Mittels noreturn
werden Funktionen markiert, die nie wieder zur aufrufenden Funktion zurückkehren. Dabei wird die Markierung einfach vor den Funktionsnamen geschrieben:
void noreturn deadEnd();
Eine nicht zurückkehrende Methode kann durch exit() oder longjmp() erzeugt werden. Folgendes Beispiel demonstriert die Verwendung von noreturn
:
#include <stdio.h> #include <stdlib.h> #include <stdnoreturn.h> void noreturn deadEnd(); int main() { deadEnd(); printf( "infinity reached!!!\n" ); return 0; } void noreturn deadEnd() { exit( 1 ); }
Der Compiler zeigt in diesem Fall keine Warnung an.
Ist eine Methode als noreturn
markiert, obwohl eine (wenn auch nur theoretische) Möglichkeit der Rückkehr besteht, weist der Compiler darauf hin:
#include <stdio.h> #include <stdnoreturn.h> void noreturn deadEnd(); int main() { deadEnd(); printf( "infinity reached!!!\n" ); return 0; } void noreturn deadEnd() { printf( "not today ;)\n" ); }
Der obige Code liefert folgende Compiler-Ausgabe:
noreturn.c:18:1: warning: ‘noreturn’ function does return [enabled by default]
In diesem Beispiel kehrt die Funktion auf jeden Fall zurück. Der Compiler zeigt auch eventuell ungewollte return
-Statements an oder warnt uns vor der Möglichkeit des Rückkehrens:
#include <stdio.h> #include <stdlib.h> #include <stdnoreturn.h> void noreturn deadEnd(); int main() { deadEnd( 3 ); printf( "infinity reached!!!\n" ); return 0; } void noreturn deadEnd( int value ) { if( value == 0 ) return; else if( value == 1 ) exit( 1 ); printf( "not today ;)\n" ); }
Dieser Code liefert gleich 2 Warnungen:
noreturn.c:18:5: warning: function declared ‘noreturn’ has a ‘return’ statement [enabled by default] noreturn.c:18:5: warning: ‘noreturn’ function does return [enabled by default]
Die erste wird durch das return
verursacht, die zweite durch die Möglichkeit des Rückkehrens zur aufrufenden Funktion.