2013-04-12 10 views
7

Gdy kompiluję program C poniżej, otrzymuję to ostrzeżenie: ‘noreturn’ function does return. To jest funkcja:Funkcja 'noreturn' zwraca

void hello(void){ 
    int i; 
    i=1; 
} 

Dlaczego to może się stać? Wszystko wywołanie tej funkcji jest hello();

EDIT: Pełne wyjście błędu:

home.c: In function ‘hello’: 
hhme.c:838:7: error: variable ‘i’ set but not used [-Werror=unused-but-set-variable] 
home.c:840:1: error: ‘noreturn’ function does return [-Werror] 
cc1: all warnings being treated as errors 
make: *** [home.o] Error 1 
+0

Czy umieścisz ostrzeżenie kompilatora dokładnie? –

+9

Czy możesz utworzyć [SSCCE] (http://sscce.org/) i pokazać nam pełny przykład? Proszę również dołączyć komunikaty _all_ i _complete_ error/warning. –

+2

Jakiego kompilatora używasz? Z jakich opcji kompilatora korzystałeś? – Bechir

Odpowiedz

24

Możliwe jest powiedzieć gcc że dana funkcja nie zwraca. Pozwala to na pewne optymalizacje i pomaga uniknąć fałszywych ostrzeżeń niezainicjowanych zmiennych.

Odbywa się to przy użyciu noreturn attribute:

void func() __attribute__ ((noreturn)); 

Jeżeli funkcja nie zwraca mimo atrybutu noreturn, kompilator emituje ostrzeżenie widzisz (która w danym przypadku zostanie przekształcona w błąd).

Skoro jesteś mało prawdopodobne, aby przy użyciu noreturn w swoim kodzie prawdopodobnym wyjaśnieniem jest to, że masz funkcję, której nazwa starcia ze standardowym noreturn funkcji, jak w poniższym przykładzie:

#include <stdlib.h> 

void exit(int) { 
}    // warning: 'noreturn' function does return [enabled by default] 

Tutaj mój exit koliduje z exit(3).

Innym oczywistym kandydatem do takiego starcia jest abort(3).

Oczywiście, jeśli twoja funkcja jest rzeczywiście nazywana hello(), sprawca prawie na pewno jest gdzieś w twojej bazie kodu.

4

Najprawdopodobniej funkcja jest oznaczona __attribute__((noreturn)). Jednak w rzeczywistości powraca (gdy kontrola osiąga koniec ciała IR, ponieważ nie wchodzi w nieskończoną pętlę, nie wywołuje innych funkcji "noreturn" itp.)

Nie widzę na czym polega twój punkt 1. oznaczanie funkcji jako nie powracającej, 2. pisanie funkcji, która nic nie robi - prawdopodobnie można po prostu wyeliminować obie opcje?

+3

Wyjaśnienie tej odpowiedzi: dla funkcji z __attribute __ ((noreturn)), jeśli treść funkcji nie kończy się nieskończoną pętlą lub wywołaniem innej funkcji noreturn, otrzymasz to ostrzeżenie. Innymi słowy, kompilator wykonuje "analizę przepływu" i może określić, czy funkcja rzeczywiście może powrócić. Pamiętaj, że na klamrze zamykającej jest domniemany powrót. – bootchk

+3

@bootchk, +1 dla "nieskończonej pętli". 'f() {}' generuje ostrzeżenie/błąd. 'f() {while (1); } 'jest w porządku. Dzięki – user3124812