2012-06-18 41 views
7

Tôi đang xem một số mã mà một người bạn gửi cho tôi, và anh ấy nói: "Nó biên dịch, nhưng không hoạt động". Tôi thấy rằng ông đã sử dụng các chức năng không có dấu ngoặc đơn, như sau:Tại sao trình biên dịch C++ không phàn nàn khi tôi sử dụng các hàm không có dấu ngoặc đơn?

void foo(){ 
    cout<< "Hello world\n"; 
} 

int main(){ 
    foo; //function without parentheses 
    return 0; 
} 

Điều đầu tiên tôi nói là "sử dụng dấu ngoặc đơn, bạn phải". Và sau đó tôi đã kiểm tra mã đó - nó biên dịch, nhưng khi thực thi không hoạt động (không có "Hello world" được hiển thị).

Vì vậy, tại sao nó biên dịch (không có cảnh báo nào từ trình biên dịch GCC 4.7), nhưng không hoạt động?

+0

Nó thực sự hoạt động. 'foo' được coi là con trỏ hàm. Dòng 'foo;' chỉ là một dòng không có hiệu lực. Nếu bạn bật cảnh báo của mình lên mức tối đa, bạn sẽ nhận được cảnh báo về tuyên bố không có hiệu lực. – RedX

+0

Tôi thấy * "cảnh báo: tuyên bố là tham chiếu, không gọi, để báo cáo‘ foo ’" * và * "cảnh báo: không có hiệu lực" *. Bạn có thể muốn biên dịch với -Wall -Wextra – Flexo

+3

(Đối với các câu hỏi trong tương lai, bạn nên đặt '#include ' và mọi thứ không gian tên để hoàn thành mẫu của mình) – Flexo

Trả lời

12

Chắc chắn cảnh báo nếu bạn đặt mức cảnh báo đủ cao.

Tên hàm đánh giá địa chỉ của hàm và là biểu thức pháp lý. Thông thường nó được lưu trong một con trỏ hàm,

void (*fptr)() = foo; 

nhưng không bắt buộc.

11

Bạn cần tăng mức cảnh báo mà bạn sử dụng. foo; là một câu lệnh biểu thức hợp lệ (tên của một hàm chuyển đổi thành một con trỏ tới hàm được đặt tên) nhưng nó không có hiệu lực.

Tôi thường sử dụng -std=c++98 -Wall -Wextra -pedantic mang đến cho:

<stdin>: In function 'void foo()': 
<stdin>:2: error: 'cout' was not declared in this scope 
<stdin>: In function 'int main()': 
<stdin>:6: warning: statement is a reference, not call, to function 'foo' 
<stdin>:6: warning: statement has no effect 
3
foo; 

Bạn đang không thực sự 'sử dụng' chức năng ở đây. Bạn chỉ sử dụng địa chỉ của nó. Trong trường hợp này, bạn đang dùng nó nhưng không thực sự sử dụng nó.

Địa chỉ của hàm (tức là tên của chúng, không có dấu ngoặc đơn) rất hữu ích khi bạn muốn chuyển hàm đó làm hàm gọi lại cho một số hàm khác.

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