2012-04-17 34 views
7

Chúng tôi có macro chức năng #define FOO(arg) foo(arg) với int foo(const char* bar);. Khi NDEBUG được định nghĩa FOO được định nghĩa là #define FOO(arg) 0, tuy nhiên điều này gây ra nhiều cảnh báo trình biên dịch bởi vì trong nhiều trường hợp, giá trị trả về của FOO không được sử dụng. Giải pháp nên làm việc với các trình biên dịch ANSI C và không gây ra cảnh báo nào. Tôi đã thử:Macro chức năng đánh giá về 0 và có thể được sử dụng làm tuyên bố

(void)0: không thể assigend để biến

static int foo(const char* bar) { return 0; }: gây không sử dụng cảnh báo chức năng tĩnh trong một số module

static inline int foo(const char* bar) { return 0; }: chỉ hoạt động với các trình biên dịch C99

Cám ơn bạn Cứu giúp!

edit1: Nó giống như macro theo dõi và được sử dụng trên toàn bộ dự án. Chủ yếu nó chỉ được sử dụng như một tuyên bố như FOO("function x called");, nhưng trong một vài trường hợp tôi thấy if (FOO("condition a")) { /* some more debug output */ }. Với NDEBUG được định nghĩa và tối ưu hóa, không có gì nên được để lại của FOO. Tôi đã không nghĩ ra điều này, nhưng tôi phải dọn dẹp đống lộn xộn này :).

edit2: Tôi nên thêm rằng phát hành gcc xây dựng những lá cờ được sử dụng: O3 Wall -ansi

EDIT3: Để bây giờ tôi đi với __inline int dummy() { return 0; }. __inline hoạt động với cả VisualC và GCC trong chế độ ansi.

+2

Bạn có thể hiển thị nhiều ví dụ về cách 'FOO() 'được sử dụng trong mã của bạn? – unwind

+3

Bạn có luôn luôn sử dụng giá trị trả về từ, ví dụ: 'printf()'? – pmg

+0

Nếu bạn không nhớ gọi foo() và chỉ muốn chắc chắn giá trị trả về được sử dụng là 0, bạn có thể sử dụng toán tử dấu phẩy và '#define FOO (arg) (foo (arg), 0)' – Eregrith

Trả lời

2

Những gì bạn có thể làm gì để ngăn chặn sự cảnh báo như sau:

#ifndef NDEBUG 
    #define FOO(arg) foo(arg) 
#else 
    #define FOO(arg) abs(0) 
#endif 

Tôi không nói rằng đây là lý tưởng (bạn phải chắc chắn rằng stdlib.h được bao gồm ở khắp mọi nơi, ví dụ) nhưng nó ngăn chặn cảnh báo.

+0

Điều này có thể hiệu quả nhưng như bạn nói nó không lý tưởng. Tôi sẽ phải kiểm tra xem trình biên dịch sẽ loại bỏ điều này trong bản phát hành. – maep

+0

@maep: Vâng tôi cũng nghĩ về vấn đề đó. Tuy nhiên, tôi * hy vọng * bất kỳ trình biên dịch phong nha sẽ loại bỏ nó trong phiên bản phát hành. BTW, GCC dường như loại bỏ nó ngay cả ở '-O0'. – Job

+0

Một số trình biên dịch có thể cảnh báo về việc gọi một hàm thuần túy và không sử dụng giá trị trả lại ... –

1

Tôi sẽ làm điều gì đó phụ thuộc vào phiên bản C. Trong tập tin tiêu đề:

#if __STDC_VERSION__ > 199900L 
inline int foo(const char* bar) { return 0; } 
#else 
int foo(const char* bar); 
#endif 

trong một đơn vị biên soạn

#if __STDC_VERSION__ < 199900L 
int foo(const char* bar) { return 0; } 
#else 
int foo(const char* bar); 
#endif 

hoặc sử dụng cho các phiên bản C trông như già một cái gì đó giống như câu trả lời của Gióp, đó là một chức năng mà chắc chắn sẽ được tối ưu hóa ra nhưng điều đó không' t đưa ra cảnh báo.

3

tôi đoán đó là một chút biên dịch chút phụ thuộc nhưng điều này nên làm việc:

#ifndef NDEBUG 
    #define FOO(arg) foo(arg) 
#else 
    #define FOO(arg) ((int)0) 
#endif 

Nó ngăn chặn các "biểu hiện không có tác dụng" cảnh báo, nó không làm gì và giá trị của nó khi được sử dụng vẫn là 0.

EDITED
có vẻ như đó là một cái gì đó không nên cầm tay như vậy (bây giờ) bạn có những điều kiện:

  • (0) hoặc ((int)0) hoạt động ít nhất trên VC 2010.
  • __noop nên hoạt động trên bất kỳ phiên bản nào của VC sau năm 2003.

VC6 không phải là vấn đề vì nó không phát ra cảnh báo C4555. Đối với các trình biên dịch khác, bạn có thể sử dụng:

  • ((void)0, 0) Nó có thể hoạt động trên nhiều trình biên dịch (có thể là trình biên dịch nhiều hơn?).
  • inline int foo(const char* bar) { return 0; } hoạt động với bất kỳ trình biên dịch C99 nào khác (như bạn đã viết, bạn có thể cần phải khai báo nó là static trên gcc).

Đối với bất kỳ trình biên dịch C thời tiền sử khác sử dụng các giải pháp được trỏ bởi @Jobs: abs(0)

+0

Thú vị, tôi tự hỏi tại sao điều này hoạt động ... Lưu ý rằng trên GCC, dàn diễn viên thậm chí không cần thiết. – Job

+0

Tôi vẫn nhận được cảnh báo với -Wall – maep

+0

@maep Bạn đang sử dụng VC? Tôi đang sử dụng 2k10 và nó không đưa ra bất kỳ cảnh báo nào (như được chỉ bởi Job trong hầu hết các trình biên dịch, ngay cả việc cast là không cần thiết). Bạn nhận được cảnh báo gì? –

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