【问题标题】:C function call without bracket不带括号的 C 函数调用
【发布时间】:2018-05-19 19:52:03
【问题描述】:

这是一个简单的 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 编译器有同样的行为吗?

【问题讨论】:

  • 不,不:fflush stdout,我在问它为什么有效。
  • 与 fflush 是一个内置函数有关,甚至可能是一个宏
  • 我无法在linux 上重现,可能是mingw 的东西。
  • 原则上,flush 后面不跟( 映射到一个函数指针。但是,stdin 如何映射为合法的延续还不是很明显。你看过 C 预处理器的输出吗? (gcc -E)?

标签: c function mingw


【解决方案1】:

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

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

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

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

但这只是因为宏魔法,而且大多数宏都受括号保护以避免与其他标记的副作用(例如运算符优先级)

你可以用这个简单的代码在没有任何包含的情况下重现它:

#define arg ("hello")

void f(const char *x)
{
}

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

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

【讨论】:

  • 查看预处理器输出可以解释这一点——这并不明显。这是“宏中表达式周围的括号”的奇怪副作用。这是“stdout 作为宏”的旧模式;尤其是现代 Linux,使 stdout 成为常​​规对象。 macOS 也是如此。
  • C 标记中的一些新内容,一次 :) 将问题标记为“mingw”,因为它在某种程度上是特定的并且可以按原样在该平台上重现
  • 玩得很好^^我太专注于fflush,所以我没有考虑这个。谢谢。
【解决方案2】:

你的问题:

请参阅让-弗朗索瓦·法布尔的回答。 有一个奇怪的措辞 标准(我并没有声称它不止于此)。

C99 7.19.1 说:

标头声明了三种类型、几个宏和 许多用于执行输入和输出的函数。

...

宏是

...

标准错误 标准输入 标准输出

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

正如基思·汤普森很久以前所说的那样 在上下文中,这表示它们是宏——但所有的描述 其他宏使用短语“扩展为”。对于标准错误, 标准输入和标准输出,它说它们 是 表达式(如果它们是 宏,并不完全正确)。

如果它们被允许声明为对象而不是宏, 然后应该更改 7.19.1p1 以允许这些声明,并且 stderr、stdin 和 stdout 的描述不应该是 一页长的连续句子。

更合理的说法是,如果它们需要是宏,那么短语“which 是表达式”应更改为“扩展为表达式”。

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

【讨论】:

    猜你喜欢
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多