作者Hyozero (大宝)
看板C_and_CPP
标题[问题] VA_ARGS 和 ##VA_ARGS 的用法
时间Tue Dec 26 15:15:47 2023
开发平台(Platform): (Ex: Win10, Linux, ...)
Linux
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
GCC
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
问题(Question):
https://zhuanlan.zhihu.com/p/514246786
##VA_ARGS 看起来是 VA_ARGS的加强版或好用版
在额外的参数数量是0时, 能够避免compile error
想请教如附件程式码
1. 第20行, 只能print出第一个参数 Message 1: ,
而不是预期的 Message 1: a = 40.00, b = 6.3246
2.第24,25,27行, compile error
这样的结果和文章写的似乎不太一致
想请教高手大大, 是不是我哪里理解有错误呢?
谢谢
喂入的资料(Input):
预期的正确结果(Expected Output):
错误结果(Wrong Output):
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
https://ideone.com/cS0XH4
补充说明(Supplement):
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 122.116.232.222 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1703574949.A.B98.html
1F:推 stupid0319: 我只用过 va_list 12/26 17:08
2F:推 gusion: 第20行展开来後,printf的format string是"Message 1: ", 12/26 18:35
3F:→ gusion: 里面没有%,所以後面参数被忽略,最後印出来就是这样 12/26 18:35
4F:推 Dracarys: 如楼上所说,第20行展开中间有逗号,没达到string conc 12/26 21:36
5F:→ Dracarys: at的效果。至於你的PRINT3跟4,##是拿来把preprocessin 12/26 21:36
6F:→ Dracarys: g tokens二合一,比如4会跟(合,合出非法pp-token已经 12/26 21:36
7F:→ Dracarys: 是UB了。作为非标准的GNU extension:##只在逗号和__VA 12/26 21:36
8F:→ Dracarys: _ARGS__中间有特殊含义,就是你所谓的加强版。 12/26 21:36
9F:推 Dracarys: BTW, preprocessor过气了,这样写比较潮: 12/26 23:19
11F:推 lc85301: 潮到我都要开除湿机了(yay 12/28 12:11
12F:推 Lipraxde: 也要 C++ 才能用这样酷酷的写法 12/29 13:38
13F:→ kao50126: 最近看标准 c23有新的__VA_OPT__ 看来是标准化gcc exte 12/29 18:15
14F:→ kao50126: nsion的行为? 12/29 18:15
15F:推 LPH66: 这个在 C++20 已经先行登场了, C23 只是跟上而已 12/29 19:04
16F:→ LPH66: 因为 __VA_ARGS__ 为空时的状况本来就很讨厌 12/29 19:04
17F:→ LPH66: gcc 用 , ## __VA_ARGS__ 去「解决」其实是 hack 12/29 19:05
18F:→ LPH66: 就是五楼提的 ## 本来是用来把两个 token 贴成一个 12/29 19:07
19F:→ LPH66: 逗号贴什麽东西都不是合法 token 所以就拿来 hack 成这行为 12/29 19:08
20F:→ LPH66: C++20 登场的 __VA_OPT__ 的用途就是把这个边界状况给解决 12/29 19:09
21F:推 kao50126: 感谢解说 12/29 19:12