Cách giải quyết trong câu hỏi là thế này:
#define EXPAND(x) x
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) EXPAND(F(__VA_ARGS__))
Ý tưởng là đưa ra một hiện variadic vĩ mô F()
:
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
thay vì viết mong muốn wrapper vĩ mô variadic của bạn như là, trong trường hợp này, ...
#define G(...) F(__VA_ARGS__)
... bạn viết G()
khi sử dụng macro EXPAND()
bổ sung. Định nghĩa thực tế của F()
không phải là vấn đề, và đặc biệt không quan trọng đối với ví dụ này là việc mở rộng macro không tạo ra mã C hợp lệ. Mục đích của nó là để chứng minh hành vi của tiền xử lý đối với các đối số macro. Cụ thể, nó cho thấy rằng mặc dù MSVC mở rộng __VA_ARGS__
thành một mã thông báo duy nhất trong macro Vĩ mô, có thể làm việc xung quanh bằng cách buộc phải mở rộng gấp đôi.
Ví dụ, bằng cách sử dụng định nghĩa workaround, Preprocessor đầu tiên mở rộng ...
G(1, 2, 3)
... để ...
EXPAND(F(1, 2, 3))
... nơi 1, 2, 3
được coi là một mã thông báo duy nhất. Việc tokenization đó không còn quan trọng khi preprocessor rescans cho các thay thế bổ sung, tuy nhiên: nó nhìn thấy các đối số riêng biệt cho macro F()
và mở rộng như mong muốn để tạo đối số cho macro EXPAND()
, thay thế nó bằng chính nó.
Nếu bạn cho rằng việc này hoạt động như dự định, nhưng phiên bản không có EXPAND()
không hoạt động (trong MSVC), bạn đã đúng.
Nguồn
2015-09-04 14:06:36
Tôi nghĩ bài đăng được liên kết không chính xác. Tôi nghĩ rằng các giải pháp đúng là 'G (...) F (EXPAND (__ VA_ARGS__))' – LPs
@ LPs, tôi nghĩ như vậy quá, nhưng hãy thử nó. –
@JohnBollinger Tôi cũng quá Linux bên trong để đưa tay lên MSVC :). Nghiêm túc, tôi đã không có MSVC để kiểm tra nó. Hãy thử dùng thử nó – LPs