gpt4 book ai didi

c - GCC##__VA_ARGS__ 技巧的标准替代方案?

转载 作者:太空狗 更新时间:2023-10-29 16:14:24 24 4
gpt4 key购买 nike

有一个well-known problem C99 中可变参数宏的空参数。

例子:

#define FOO(...)       printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)

FOO("this works fine");
BAR("this breaks!");
BAR()的使用根据 C99 标准,以上确实是不正确的,因为它将扩展为:
printf("this breaks!",);

请注意尾随逗号 - 不可用。

一些编译器(例如:Visual Studio 2010)会悄悄地为您去除尾随逗号。其他编译器(例如:GCC)支持放置 ##前面 __VA_ARGS__ ,像这样:
#define BAR(fmt, ...)  printf(fmt, ##__VA_ARGS__)

但是有没有符合标准的方法来获得这种行为?
也许使用多个宏?

现在, ##版本似乎得到了很好的支持(至少在我的平台上),但我真的更愿意使用符合标准的解决方案。

先发制人:我知道我可以只写一个小函数。我正在尝试使用宏来做到这一点。

编辑 :这是我为什么要使用 BAR() 的示例(虽然很简单):
#define BAR(fmt, ...)  printf(fmt "\n", ##__VA_ARGS__)

BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);

这会自动向我的 BAR() 日志记录语句添加一个换行符,假设 fmt始终是双引号 C 字符串。它不会将换行符打印为单独的 printf(),如果日志记录是行缓冲的并且异步来自多个源,这将是有利的。

最佳答案

可以避免使用 GCC 的 ,##__VA_ARGS__如果您愿意接受可以传递给可变参数宏的参数数量的一些硬编码上限,如 Richard Hansen's answer to this question 中所述.但是,如果您不想有任何此类限制,据我所知,仅使用 C99 指定的预处理器功能是不可能的;您必须对该语言使用某种扩展。 clang 和 icc 已经采用了这个 GCC 扩展,但 MSVC 没有。

早在 2001 年,我在 document N976 中编写了用于标准化的 GCC 扩展(以及允许您使用 __VA_ARGS__ 以外的名称作为其余参数的相关扩展)。 ,但没有得到委员会的任何回应;我什至不知道有没有人读过。 2016年在N2023再次提出,我鼓励任何知道该提案将如何在评论中让我们知道的人。

关于c - GCC##__VA_ARGS__ 技巧的标准替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5588855/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com