Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Malware / Trojaner / VirenKernelFlirt(01.10.2026 um 06:47 Uhr)
•
IT Security NachrichtenApp-arently it's legit.(01.10.2026 um 07:00 Uhr)
•
IT Security NachrichtenAnthropic’s Court Battles.(01.10.2026 um 07:00 Uhr)
••••••••
Malware / Trojaner / VirenKernelFlirt(01.10.2026 um 06:47 Uhr)
•
IT Security NachrichtenApp-arently it's legit.(01.10.2026 um 07:00 Uhr)
•
IT Security NachrichtenAnthropic’s Court Battles.(01.10.2026 um 07:00 Uhr)
••••••••
Intelligence View
⚡ tsecurity.de Intelligence

C语言得到变参数量的宏,0参数不会错误返回1,gcc和msvc都测试通过

参考 https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments 我原先用的是: #define _expand(x) x #define _numargs(_0, _1, _2, _3, _4, _5, …

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

参考 https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments



我原先用的是:




#define _expand(x) x
#define _numargs(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, N, ...) N
#define numargs(...) _expand(_numargs(_, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))






msvc必须要用_expand套一下,原因据说是参数展开时机问题,但零参数会得到错误结果1,gcc有另外的问题,就是不能使用比如-std=c99 -std=c23,否则零参数也是1,原因是##是gcc扩展,参见https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html,而标准c直到c23才加入__VA_OPT__,有意思的是msvc也支持##。



高赞那个用(sizeof((int[]){__VA_ARGS__})/sizeof(int))的,首先msvc必须高版本,且会报C4047类型不匹配警告,而gcc则是错误无法编译。



只有下面6赞的回答是完美的,我稍微调整了下,以适配个人风格:




#define _numargs_call(__arg_0, __arg_1) __arg_0 __arg_1
#define _numargs_select(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, __arg_0, ...) __arg_0
#define numargs(...) _numargs_call(_numargs_select, (_, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))






msvc现在是用_numargs_call套一下,零参数不会出问题了,甚至古老的vs2007/wdk7.1也正常。



测试代码:




int main() {
printf("numargs = %d\n", numargs());
printf("numargs = %d\n", numargs(1));
printf("numargs = %d\n", numargs(1, 3.14));
printf("numargs = %d\n", numargs(1, 3.14, "hello"));
return EXIT_SUCCESS;
}






执行cl test.c && test.exe或gcc -o test.exe test

.c && ./test.exe
,结果都是:




numargs = 0
numargs = 1
numargs = 2
numargs = 3


Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten C语言得到变参数量的宏,0参数不会错误返回1,gcc和msvc都测试通过

Thematisch verwandte Begriffe: C语言得到变参数量的宏0参数不会错误返回1gcc和msvc都测试通过 · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag