2013-04-12 32 views
7

Khi tôi biên dịch chương trình C bên dưới, tôi nhận được cảnh báo này: ‘noreturn’ function does return. Đây là chức năng:Chức năng ‘noreturn’ trả lại

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

Tại sao nó có thể xảy ra? Tất cả các cuộc gọi đến chức năng này là hello();

EDIT: Các đầy đủ lỗi đầu ra:

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

bạn có thể đăng cảnh báo trình biên dịch chính xác không? –

+9

Bạn có thể tạo một [SSCCE] (http://sscce.org/) và cho chúng tôi xem một ví dụ hoàn chỉnh không? Ngoài ra, vui lòng bao gồm _all_ và _complete_ thông báo lỗi/cảnh báo. –

+2

Bạn đang sử dụng trình biên dịch nào? Bạn đã sử dụng các tùy chọn trình biên dịch nào? – Bechir

Trả lời

24

Có thể nói gcc rằng một chức năng cụ thể không bao giờ trở lại. Điều này cho phép tối ưu hóa nhất định và giúp tránh cảnh báo giả mạo của các biến chưa được khởi tạo.

này được thực hiện bằng cách sử dụng noreturn attribute:

void func() __attribute__ ((noreturn)); 

Nếu chức năng không trở lại mặc dù thuộc tính noreturn, trình biên dịch phát ra cảnh báo bạn đang thấy (mà trong trường hợp của bạn được chuyển đổi thành một lỗi).

Vì bạn khó có khả năng được sử dụng noreturn trong mã của bạn, lời giải thích khả năng là bạn có một chức năng có tên đụng độ với một noreturn chức năng tiêu chuẩn, như trong ví dụ dưới đây:

#include <stdlib.h> 

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

Ở đây, của tôi exit xung đột với exit(3).

Một ứng cử viên rõ ràng khác cho cuộc xung đột như vậy là abort(3).

Tất nhiên, nếu chức năng của bạn thực sự được gọi là hello(), thủ phạm gần như chắc chắn ở đâu đó trong cơ sở mã của bạn.

4

Có thể, chức năng được đánh dấu bằng __attribute__((noreturn)). Tuy nhiên, nó thực tế trở lại (khi kiểm soát đạt đến cuối của cơ thể irs, vì nó không nhập một vòng lặp vô hạn, nó không gọi các chức năng "noreturn" khác, vv)

Tôi không thấy những gì quan điểm của bạn là trong 1. đánh dấu các chức năng như không trở về, 2. viết một chức năng mà không có gì - có lẽ bạn chỉ có thể loại bỏ cả hai?

+3

Làm rõ câu trả lời này: đối với một hàm có __attribute __ ((noreturn)), nếu phần thân hàm không kết thúc bằng vòng lặp vô hạn hoặc gọi hàm khác noreturn, bạn sẽ nhận được cảnh báo này. Nói cách khác, trình biên dịch thực hiện "phân tích lưu lượng" và có thể xác định xem hàm thực sự có thể trả về hay không. Hãy nhớ rằng có một trở lại tiềm ẩn ở cú đúp đóng. – bootchk

+3

@bootchk, +1 cho "vòng lặp vô hạn". 'f() {}' tạo ra cảnh báo/lỗi. 'f() {trong khi (1); } 'được rồi. Cảm ơn – user3124812

Các vấn đề liên quan