2016-11-04 14 views
5

Có cách nào để cảnh báo về việc bỏ lỡ tên đối số giữa khai báo hàm và định nghĩa của nó không?C++ Làm thế nào để cảnh báo về sự khác biệt giữa tên đối số trong khai báo hàm và định nghĩa

Tuyên bố

double divide(int a, int b); 

Definition

double divide(int b, int a) 
{ 
    return a/b; 
} 

Đối với một người sử dụng, đó sử dụng chức năng divide, sẽ mong đợi a/b và kết quả là không b/a.

Tôi biết, trình biên dịch không thể làm điều đó, nhưng có một số công cụ phân tích tĩnh có thể làm điều đó không? Nếu có, cái nào?

+0

đối số chỉ có vị trí trong C. Tôi đã thử nghiệm với '-Wall' và không may mắn BTW. –

+0

Vì lý do đơn giản là nếu ai đó không biết cách hàm được khai báo, có thể nhận được kết quả không mong muốn từ nó. Ví dụ: a/b! = B/a – lucab0ni

+1

tất nhiên, đó là một vấn đề thực sự. Nhưng trong C không thể làm được. Tôi chắc rằng một số máy phân tích mã như ClokWork hoặc Logiscope đề xuất các kiểm tra như vậy. –

Trả lời

10

Bạn có thể sử dụng tính năng ngăn nắp. Gọi nó là một trình biên dịch là một chút của một căng, nhưng có thể có một tùy chọn để làm cho clang phát ra cảnh báo clang-gọn gàng. Tùy chọn cụ thể bạn muốn là readability-inconsistent-declaration-parameter-name.

0

Trình biên dịch không quan tâm đến tên đối số trong sự khai báo của bạn, thậm chí bạn có thể viết void foo(int, int);, do đó không có sự không khớp và không có cảnh báo như vậy. Nếu bạn vì một lý do nào đó, việc này không phù hợp, chỉ cần bỏ qua các tên đối số trong các khai báo.

+1

"chỉ bỏ qua các tên đối số trong các khai báo", tôi nghĩ lý do anh ta muốn cảnh báo là vì vậy chức năng này rõ ràng chỉ bằng cách nhìn vào tuyên bố. – George

+0

@George, có lẽ. Nhưng những gì là "rõ ràng" về các biến được gọi là "a" và "b"?Tôi thấy một 'phân chia' của hai số nguyên được gọi là' a' và 'b'. –

+1

@AaronMcDaid: Tôi nghĩ một ví dụ thực tế hơn sẽ là 'void copy (int * src, int * dest)' đổi tên sẽ là * bad *. (Phải, tôi nhận ra 'src' nên là' const int * '). –

0

Bạn chỉ quan tâm đến việc kiểm tra mã hiện có hay muốn đảm bảo rằng mã tránh được sự cố này và sẵn sàng thiết kế lại giao diện?

Trong trường hợp sau:

Nếu bạn có nhiều đối số cùng loại sau đó mâu thuẫn có thể là một vấn đề (và tôi đã thấy tồi tệ hơn ví dụ của bạn):

void foo(bool fast, bool small, bool trivial); 
foo(true, false, false); 

gì bạn đang yêu cầu cho là một cách để đảm bảo rằng tuyên bố và định nghĩa của foo là nhất quán - nhưng bạn bỏ qua những mâu thuẫn giữa lời gọi và tuyên bố.

Một giải pháp khác là thay vì tạo đối số-struct với setRoutines. Một cái gì đó như:

struct FooArg { 
    bool fast, small, trivial; 
    FooArg &setFast(bool fast_) {fast=fast_;return *this;}; 
    ... 
}; 
void foo(FooArg const&); 
foo(FooArg().setFast(true).setSmall(false)...); 

Sau đó bạn tránh sự không thống nhất giữa tuyên bố, định nghĩa và cuộc gọi nhưng phải tiết lộ chi tiết hơn. (Tôi chắc chắn có câu trả lời về kỹ thuật này ở đâu đó.)

+0

Tôi chỉ quan tâm đến việc kiểm tra mã. Trong trường hợp thực tế của tôi, khai báo được tạo ra bởi một công cụ, thay vào đó định nghĩa được thực hiện bằng tay. – lucab0ni

+0

Và tôi giả sử rằng công cụ tạo ra các định nghĩa sơ khai sẽ là quá nhiều công việc, đặc biệt nếu công cụ phải được chạy lại để tạo ra các khai báo mới- trong khi vẫn giữ một số định nghĩa hiện có. –

+0

vâng, đó là điểm – lucab0ni

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