2012-07-23 14 views
14

Tôi đang cố gắng để xác định một phương pháp học cho các bản in debug mà sẽ hành xử giống như printf:Làm thế nào tôi nên sử dụng đúng __attribute__ ((định dạng (printf, x, y))) bên trong một phương thức lớp trong C++?

inline void debug(const char* fmt, ...) __attribute__ ((format (printf, 1, 2))) 

này phàn nàn về:

error: format string argument not a string type 

Tôi nhắc lại rằng một tuyên bố phương pháp lớp học có một tham số ngầm this , vì vậy tôi đã thay đổi vị trí của các tham số thành 2, 3:

inline void debug(const char* fmt, ...) __attribute__ ((format (printf, 2, 3))) 

và bây giờ nó biên dịch, nhưng có vẻ như các tham số được dịch chuyển, như thể tham số this đã được xử lý như một phần của danh sách đối số.

Làm cách nào để biết hàm this không phải là một phần của chuỗi mà tôi muốn in?

+0

Bạn có thể sử dụng các mẫu variadic không? Nếu có, bạn có thể tạo [printf print an toàn] (http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html) – chris

+1

Đừng suy nghĩ quá nhiều về 'this'. Nó không phải là một đối số rõ ràng, thời gian. Chỉ cần làm theo hướng dẫn GCC, cho biết rằng đối với các hàm thành viên, bạn phải thêm 1 vào các đối số thuộc tính 'format'. Nó chỉ là một quy tắc mờ đục, được cung cấp bởi bạn bởi nhà cung cấp phần mở rộng của trình biên dịch. –

+2

printf (2, 3) là đúng. Xác định "có vẻ như bị dịch chuyển" ...? –

Trả lời

15

Bạn đã hoàn thành. this là đối số 1, do đó, bằng cách nói format(printf, 2, 3) bạn đang nói trình biên dịch rằng bạn KHÔNG in this, bạn đang in đối số 2 (fmt) với các đối số bổ sung sau đó.

+0

Điều đó có ý nghĩa nhưng tôi tự hỏi tại sao điều này không được ghi lại ở bất cứ đâu – dashesy

+1

@dashesy: ​​nó được ghi lại trong trang thông tin gcc cho thuộc tính 'format' ... –

+1

bạn đúng [ở đây] (https: //gcc.gnu. org/onlinedocs/gcc/Common-Function-Attributes.html # Common-Function-Attributes): ** Vì các phương thức C++ không tĩnh có một đối số ngầm định, các đối số của các phương thức như vậy sẽ được tính từ hai, không phải một, khi đưa ra các giá trị cho chuỗi chỉ mục và kiểm tra đầu tiên . ** – dashesy

2

Vì nó chỉ hoạt động cho gcc, nên xác định theo cách này để tránh lỗi trên các trình biên dịch khác.

#ifdef __GNUC__ 
      __attribute__ ((format(printf, 2, 3))) 
#endif 
+2

Đó là một điểm tốt nói chung, nhưng nó không phải là một vấn đề đối với tôi, vì đây là một cơ sở mã nội bộ được xây dựng bằng cách sử dụng một dòng chảy nghiêm ngặt. –

+3

Bạn cũng có thể sử dụng '#ifndef __GNUC__ #define __attribute __ (a)'. Sau đó, bạn có thể sử dụng bất kỳ thuộc tính nào. – cubuspl42

2

Điều trị thành viên tĩnh giống như không phải thành viên. Các cuộc thảo luận đã cho tôi câu trả lời, nhưng đó là đáng chú ý cho người khác:

  • chức năng phi thành viên làm việc với 1,2
  • hàm thành viên tĩnh làm việc với 1,2
  • không tĩnh các hàm thành viên coi 'this' là # 1, vì vậy cần 2,3

Tôi tìm thấy điều này vì chúng tôi có một số quy trình sử dụng trình trợ giúp nhật ký như thế này và 1 trong số 4 yêu cầu __attribute__ ((format(printf, 2, 3))) ee làm việc tốt với __attribute__ ((format(printf, 1, 2))) - hóa ra nó không phải là tĩnh ...