2011-01-24 27 views
29

Đối với các trình gỡ lỗi, tôi thường sử dụng Clang, vì nó định dạng cảnh báo và lỗi tốt hơn và giúp bạn dễ dàng theo dõi chúng hơn và sửa chúng.Macro biến thể không chuẩn?

Nhưng thời gian gần đây sau khi thêm một Macro với đối số variadic, Clang nói với tôi như sau (từ một dự án dummy):

main.cpp:5:20: warning: named variadic macros are a GNU extension [-Wvariadic-macros] 
#define stuff3(args...) stuff_i(args) 

Tôi biết rằng macroname(args...) biên dịch tốt trong một loạt các trình biên dịch, bao gồm VisualStudio, Sunstudio và tất nhiên là GCC. Nhưng chỉ để chắc chắn rằng kêu vang là đúng, tôi đã cố gắng hai cách khác để mở rộng các đối số variadic:

Số 1:

#define stuff1(...) stuff_i(...) 

Số 2:

#define stuff2(...) stuff_i(__VA_ARGS__) 

Trên cả tôi nhận được tin nhắn:

main.cpp:3:16: warning: variadic macros were introduced in C99 [-Wvariadic-macros] 

... Điều này khiến tôi tự hỏi liệu macro Variadic có thực sự là một phần tiêu chuẩn của C++ hay không nd tất nhiên tôi biết rằng Preprocessor được giải thích một cách độc lập)?

+1

C99 và C++ 0x chính thức hỗ trợ phiên bản 2. C++ 03 không hỗ trợ bất kỳ macro variadic.Phiên bản 1 là một phần mở rộng cụ thể GCC – sellibitze

+0

(như tên của bạn) khi bạn biên dịch với GCC có tùy chọn '-pedantic' sẽ báo cáo các phần mở rộng được sử dụng. Ví dụ như Variable Length Array hoặc Variadic Macros. Trong GCC, chúng được bao gồm đơn giản bởi vì vì chúng là một phần của C99, nên logic đã được thực hiện, vì vậy nó phải có ý tưởng tốt để cho lợi ích dân gian C++ :) –

+0

@Matthieu M: Đúng vậy, tôi cũng nghĩ rằng tính năng này sẽ là một phần của C++, vì nó đã là một phần của C99 ... thú vị, gcc không nói rằng tên là variadic macro thực sự là một phần mở rộng GNU, nhưng thay vì chỉ nói rằng chúng không phải là một phần của tiêu chuẩn: 'warning: ISO C không cho phép tên là variadic macros' –

Trả lời

36

Trích Wikipedia:

macro Biến đối số đã được giới thiệu vào năm 1999 trong các tiêu chuẩn ISO/IEC 9899: 1999 (C99) sửa đổi các tiêu chuẩn ngôn ngữ C, và vào năm 2011 trong ISO/IEC 14882: 2011 (C++ 11) sửa đổi tiêu chuẩn ngôn ngữ C++.

Vì vậy, nó chuẩn từ C99 và C++ 11 trở đi, nhưng phần mở rộng của GNU trong C++ 03.

4

Ở dạng ví dụ của bạn "Số 2", chúng là tiêu chuẩn trong C99 và thường là bộ tiền xử lý của trình biên dịch C++ là giống nhau cho trình biên dịch C và C++.

Chúng cũng được hỗ trợ Microsoft VC++ mặc dù khả năng chống bướng bỉnh của nó đối với tuân thủ C99. Vì vậy, giữa đó và GCC có rất ít lý do để tránh sử dụng chúng. Ngay cả trên hầu hết các hệ thống nhúng trình biên dịch tôi sử dụng chúng được hỗ trợ.

Tránh biểu mẫu "Số 1", tuy nhiên, đó là GCC cụ thể và không nghi ngờ gì nữa.

0

Tiêu chuẩn nói trong thay 16,3 Macro:

Từ định _ _ VA_ARGS _ _ sẽ chỉ xảy ra trong việc thay đổi danh sách của một macro chức năng giống như sử dụng các ký hiệu lược trong các thông số.

26

Kể từ C++ 11, macro biến thể hiện được bao gồm trong tiêu chuẩn C++. Phần 16.3 của tiêu chuẩn C++ 11 chỉ định các macro variadic sao cho chúng tương thích với các macro variadic từ C99 (dạng thứ hai trong câu hỏi).

Dưới đây là một ví dụ về một định nghĩa macro variadic tiêu chuẩn phù hợp trong C++:

#define foo(x, y, ...) bar(x, y, __VA_ARGS__) 
+1

Đó là sự phù hợp tiêu chuẩn, nhưng nó cũng bị lỗi phẩy, nếu Wikipedia được tin tưởng. –

+0

@AlexeiAverchenko: Tôi đã thấy trong tài liệu gcc rằng dấu phẩy sẽ bị xóa nếu không có gì được đặt trong ... tuy nhiên hôm nay tôi chuyển một số mã sang tiếng kêu và tôi nhận được lỗi 'expression expression' và tôi chưa thông qua hiểu nó. có thể liên quan –

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