CWKSC's blog | 博客 (已棄用)

Visual Studio 2019 和 C++20 的宏

Featured image

目錄: C/C++ Macro 宏系列 | CWKSC’s blog | 博客

Visual Studio 2019 的預處理器更新了

C++ 20 的宏也加了一點新東西

以前某些語法真的是 bug

這裏會參考MSVC experimental preprocessor overview

Announcing full support for a C/C++ conformant preprocessor in MSVC

的内容

▌啟用新的預處理器

右鍵點擊專案 > 屬性 > C/C++ > 命令列

/Zc:preprocessor /std:c++latest 放到其他選項

套用 > 確定

▌可變參數宏的逗號省略

傳統的 MSVC 預處理程序會始終在空的 __VA_ARGS__ 替換前刪除逗號

新的預處理器更緊密地遵循其他流行的跨平台編譯器的行為

對於要刪除的逗號,可變參數必須丟失(不僅僅是空)

並且必須用 ## 運算符

#define FUNC(a, ...) func(a, ## __VA_ARGS__)

FUNC(1)  // 可變參數丟失
-> func(1)

FUNC(1,)  // 可變參數沒有丟失,只是空
-> func(1,)

FUNC(1, 2)
-> func(1, 2)

▌宏參數 unpacked【錯誤修復】

傳統的預處理器處理 __VA_ARGS__ 時會視為一個整體的 Token 來處理

新的預處理器不會這樣了,會 unpacked 宏參數

傳統的預處理器:

#define get_args0(args0, ...) args0
#define foo(...) get_args0(__VA_ARGS__)

foo(x, y)
get_args0(__VA_ARGS__)
get_args0(x, y)  // x, y 被視為一個整體
x, y

新的預處理器:

#define get_args0(args0, ...) args0
#define foo(...) get_args0(__VA_ARGS__)

foo(x, y)
get_args0(__VA_ARGS__)
get_args0(x, y)
x

__VA_OPT__(<Token>)

C++ 20 可變參數宏的新功能

它會判斷 ... 有沒有輸入參數

當可變參數丟失(不僅僅是空的)

不會展開括弧裏的 Token

反之而言,沒有丟失則展開

一個示例用法是標準化的逗號分隔

#define M(X, …) X __VA_OPT__(,) __VA_ARGS__
M(3) // expands to 3
M(3,) // expands to 3,
M(3, 4) // expands to 3, 4

注意

#define F(...)  f(0 __VA_OPT__(,) __VA_ARGS__)
#define EMP

F(a, b, c) // replaced by f(0, a, b, c)
F() // replaced by f(0)
F(EMP) // replaced by f(0) // 注意
CWKSC

Author 作者

CWKSC

喜歡編程,會一點點鋼琴,會一點點畫畫,喜歡使用顏文字 About me 關於我

For any comments or discussions on my blog post, you can open an issue here

對於我博客文章的任何評論或討論,可以在這裏開一個 issue

Feel free to give your comments. OW<