没有括号

时间:2018-05-19 19:52:04

标签: c function mingw

这是一个简单的C程序:

#include <stdio.h>

int main(void)
{
    printf("Display something\n");
    fflush stdout;
    return 0;
}

使用msys2 mingw-w64 gcc版本7.3.0和选项-Wall进行编译,一切正常,就好像第5行是fflush(stdout);一样。

我尝试使用自己的函数重现这样的调用,但是我得到了完全预期的错误

src/main.c: In function 'int main(int, char**)':
src/main.c:5:18: error: expected ';' before 'parameter'
  custom_function parameter;
                  ^~~~~~~~~

那么,fflush函数会发生什么?有人可以解释一下吗?你和其他C编译器有相同的行为吗?

2 个答案:

答案 0 :(得分:13)

让我们看看预处理器输出(使用MinGW和gcc -E test.c命令行):

   fflush 
# 5 "test.c" 3
          (&(* _imp___iob)[1])
# 5 "test.c"
                ;

如您所见stdout是一个用括号扩展为(&(* _imp___iob)[1])的宏。

所以编译器使用这些括号,语法没问题。

但这仅仅是因为宏观魔法,以及大多数宏受括号保护以避免与其他令牌产生副作用(例如运算符优先)的事实

您可以使用以下简单代码重现该内容:

#define arg ("hello")

void f(const char *x)
{
}

int main(int argc, char** argv)
{
    f arg;
    return 0;
}

当然这是不好的做法,混淆了IDE(和人类),所以就是不要这样做。

答案 1 :(得分:0)

你的问题:

enter image description here

见Jean-FrançoisFabre的回答。 在措辞中有一个奇怪的地方 标准(我没有声称它不仅仅是那个)。

C99 7.19.1说:

  

标题声明了三种类型,几个宏和   许多用于执行输入和输出的功能。

     

...

     

宏是

     

...

     

stderr的   标准输入   标准输出

     

是指向“指向FILE的指针”类型的表达式   FILE对象分别与标准错误相关联,   输入和输出流。

正如Keith Thompson很久以前所说的那样 在上下文中,这表示它们是宏 - 但是所有的描述 其他宏使用短语“扩展为”。对于stderr, stdin和stdout,它说他们表达式(如果他们是的话) 宏,并不严格正确。)

如果他们被允许,比如声明对象而不是宏, 然后应该更改7.19.1p1以允许这些声明,和 stderr,stdin和stdout的描述不应该是 一页长期的连续判决。

更合理的是,如果他们 需要是宏,那么短语“哪个 表达式“应该更改为”,扩展为表达式“。

不保证它们是宏。在你的情况下, 你很幸运,宏扩展到带有保护括号的表达式。 隐藏实际内容的邪恶宏观的一个纯粹例子。