复合文字和类似函数的宏 : bug in gcc or the C standard?

标签 c gcc c-preprocessor c99 compound-literals

在 C99 中,我们有复合文字,它们可以传递给函数,如下所示:

f((int[2]){ 1, 2 });

但是,如果 f 不是一个函数而是一个类似函数的宏,gcc 会对此感到厌烦,因为预处理器将其解析为两个参数而不是一个参数,“( int[2]){ 1”和“2 }”。

这是 gcc 或 C 标准中的错误吗?如果是后者,那几乎排除了所有透明使用类函数宏的可能性,这似乎是一个巨大的缺陷......

编辑:例如,人们希望以下内容是一个符合规范的程序片段:

fgetc((FILE *[2]){ f1, f2 }[i]);

但是由于 fgetc 可以作为一个宏来实现(尽管需要保护它的参数并且不对其求值超过一次),这段代码实际上是不正确的。这让我感到惊讶。

最佳答案

这个“错误”自 C89 以来就存在于标准中:

#include <stdio.h>

void function(int a) {
    printf("%d\n", a);
}

#define macro(a) do { printf("%d\n", a); } while (0)

int main() {
    function(1 ? 1, 2: 3); /* comma operator */
    macro(1 ? 1, 2: 3);    /* macro argument separator - invalid code */
    return 0;
}

我实际上并没有通过标准来检查这个解析,我已经接受了 gcc 的话,但非正式地需要一个匹配的 : 到每个 ? 胜过运算符优先级和参数列表语法以使第一个语句有效。第二个就没有这样的运气了。

关于复合文字和类似函数的宏 : bug in gcc or the C standard?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5558159/

相关文章:

c - 将 C 代码从 Linux 移植到 FreeBSD 时出现语法错误

c - 链接C代码时如何判断符号的定义位置

c - 如何使用 gcc 制作 .o?

c - C 中堆栈操作中的指针变量与全局变量

Android中间件c程序: Unable to create directory,只读文件系统

java - 我可以将 C# 和 Java 代码放在同一个文件中以便更轻松地移植我的代码吗?

C 预处理器定义每个字节都是 0xFF 的给定类型的值?

c - 预处理器 c,[常量或变量]

c - 为什么 gets() 比 scanf() 更危险?

gcc - 为什么 C 允许缺少函数声明?