2010-02-23 13 views
32

Trong khi bắt đầu với một số VS2005 mã tạo MFC, tôi nhận thấy nó gạt một phương thức với một cái gì đó như thế này:Tại sao mã C++ thiếu một tên đối số chính thức trong một biên dịch định nghĩa hàm mà không có cảnh báo?

void OnDraw(CDC* /*pDC*/) 
{ 
    ... 
    // TODO: Add your code here 
} 

Vì vậy, tất nhiên, ngay sau khi tôi thêm một cái gì đó tôi nhận ra tôi cần thiết để bỏ comment PDC luận chính thức để biên dịch, nhưng tôi đang bối rối như thế nào/tại sao một ++ chức năng C có thể biên dịch (không có cảnh báo) khi tranh luận chính thức chỉ có một kiểu và không phải là một tên:

void foo(int) 
{ 
    int x = 3; 
} 
int main() 
{ 
    foo(5); 
    return 0; 
} 

shouldn' Điều này tạo ra ít nhất một cảnh báo (với -Wall hoặc/W4)? Nó dường như không. Tui bỏ lỡ điều gì vậy? Có trường hợp nào hữu ích hay chỉ vì trình biên dịch không thể cho biết sự khác biệt giữa khai báo hàm (chỉ loại yêu cầu) và định nghĩa (được chỉ định đầy đủ) cho đến sau khi dòng đã được xử lý?

Trả lời

39

Vì đôi khi bạn có thông số được yêu cầu bởi giao diện nhưng chức năng không sử dụng nó. Có lẽ tham số không còn cần thiết nữa, chỉ cần thiết trong các hàm khác phải sử dụng cùng một chữ ký (đặc biệt để chúng có thể được gọi thông qua con trỏ) hoặc chức năng chưa được triển khai. Có các tham số không được sử dụng có thể đặc biệt phổ biến trong mã được tạo hoặc mã khung vì lý do này (và đó có thể là lý do mã MFC tạo ra có tên được nhận xét). Vì lý do tại sao không có cảnh báo - tôi đoán đó là bởi vì cho dù đây là một vấn đề là một điều chủ quan và những người khác (đặc biệt là những người triển khai trình biên dịch) không thấy nó như là một vấn đề. Khi bạn thực sự sử dụng tham số, bạn sẽ nhận được trình biên dịch phàn nàn nếu bạn quên bỏ ghi chú tên để bạn nhận được trình biên dịch chỉ phàn nàn khi bạn thực sự cần nó (phiên bản trình biên dịch của YAGNI nhanh nhẹn: "You Aren ' t Gonna Neet It "triết học". Ngược lại dường như thường xảy ra khi bạn quay lên cảnh báo - các tham số được đặt tên không được sử dụng tạo cảnh báo - một lần nữa đó có thể là lý do tại sao hàm được tạo ra có tên được nhận xét.

+0

Như một lưu ý bổ sung, nhiều trình biên dịch có một pragma để vô hiệu cảnh báo tham số không sử dụng - có liên quan hơn khi tham số * có * tên khóa học - chính xác vì có lý do hợp lệ tại sao điều này có thể xảy ra. Một số người thích để lại tên trong anyway, để cho biết mục đích sử dụng (theo giao diện), mặc dù nó không được sử dụng trong trường hợp này. – Steve314

+1

Tôi đoán điều đó có ý nghĩa - tôi đoán nó là một cái gì đó dọc theo những dòng đó, nó dường như (với tôi) giống như một điều kiện cạnh bất thường để cho phép rõ ràng, khi (như đã nói bên dưới) C không cho phép nó. Nhưng quan điểm của bạn về các cuộc gọi đa hình chắc chắn là hợp lệ, và có ý nghĩa cho C++ đã xem xét nó. –

15

Lý do phổ biến nhất mà tôi đã nhìn thấy là để ngăn chặn những lời cảnh báo biến không sử dụng trình biên dịch sẽ ném lên cho:

#include <iostream> 

void foo(int source) 
{ 
    std::cout << "foo()" << std::endl; 
} 

int main() 
{ 
    foo(5); 
    return 0; 
} 

gcc nói: main.cc:3: warning: unused parameter 'source'

Có hai cách phổ biến để thoát khỏi cảnh báo: comment tên biến hoặc loại bỏ nó hoàn toàn:

void foo(int /*source*/) 
{ 
    std::cout << "foo()" << std::endl; 
} 

so

void foo(int) 
{ 
    std::cout << "foo()" << std::endl; 
} 

Tôi đặc biệt khuyên bạn nên nhận xét về việc xóa. Nếu không, các lập trình viên bảo trì của bạn sẽ phải tìm ra tham số đó đại diện cho một số cách khác.

Qt (và có lẽ các khuôn khổ khác) cung cấp một macro mà ngăn chặn cảnh báo không cần thiết để bình luận hoặc xoá tên biến: Q_UNUSED(<variable>):

void foo(int source) 
{ 
    Q_UNUSED(source); // Removed in version 4.2 due to locusts 
    std::cout << "foo()" << std::endl; 
} 

này cho phép bạn gọi ra trong cơ thể hàm biến là không được sử dụng và cung cấp một nơi tuyệt vời để ghi lại tài liệu lý do tại sao nó không được sử dụng.

+1

Đó là lý trí. (BTW, C cần tên tham số) – AProgrammer

+0

@AProgrammer: Câu hỏi là về C++, không C. – Bill

+2

@Bill: nhưng nó vẫn là một lưu ý có giá trị (tôi thấy mình thỉnh thoảng bị kích thích bởi sự khăng khăng của C về tên tham số) –

2

Nó biên dịch vì tiêu chuẩn ngôn ngữ cụ thể cho biết phải biên dịch. Không có câu trả lời nào khác. Đây là một trong các bit tạo ra C++ khác với các tên tham số C. Trong C trong định nghĩa hàm phải có mặt, trong C++ chúng là tùy chọn.

Tôi thực sự tự hỏi tại sao bạn hỏi câu hỏi "tại sao" của mình. Bạn có thấy bất cứ điều gì không tự nhiên, bất thường hay phi lý trong hành vi này không?

+3

Tôi đang tìm kiếm điều gì đó dọc theo dòng "tại sao tiêu chuẩn cho phép điều này", như các câu trả lời khác đã gợi ý. Câu trả lời "Nó biên dịch bởi vì nó nên" là ... rõ ràng để nói rằng ít nhất. –

+1

@Andrew Coleson: Vâng, đối với tôi khả năng bỏ qua tên tham số (whin nó không được sử dụng) trông tự nhiên, một lý do đằng sau nó - hiển nhiên. Tôi có thời gian khó hiểu tại sao ai đó sẽ hỏi câu hỏi "tại sao". Trên thực tế, tôi thà mong đợi một người nào đó hỏi tại sao C * không * cho phép điều này, không phải lý do tại sao C++ làm. Vì vậy, câu trả lời của tôi ở trên được cho là có ý nghĩa sau: nó là hợp pháp trong C++ vì đặc tả C++ cuối cùng cho phép nó (như trong "mọi người đã chờ đợi nó, và trong C++ nó cuối cùng đã được thực hiện"). – AnT

+0

"Mọi người đều muốn nó trong C và trong C++ nó cuối cùng đã được thực hiện" là một câu trả lời hữu ích cho "Tại sao?", Cảm ơn bạn. –

4

C++ 11 N3337 dự thảo tiêu chuẩn

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf nói nó là hợp pháp tại 8.4.1/6 "định nghĩa Chức năng> Nói chung":

Lưu ý: các thông số chưa sử dụng không cần phải được đặt tên. Ví dụ,

void print(int a, int) { 
    std::printf("a = %d\n",a); 
} 

Chính xác hơn, 8.4.1/1 nói rằng ngữ pháp cho các định nghĩa chức năng là

function-definition: 
    attribute-specifier-seqopt decl-specifier-seqopt 
    declarator virt-specifier-seqopt function-body 

Sau đó, nếu bạn làm theo các định nghĩa ngữ pháp, ví dụ trong "Tóm tắt ngữ pháp của Phụ lục A", bạn sẽ thấy rằng các tên là tùy chọn.

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