使用 clang 与 gcc 编译嵌套函数

Ami*_*mir 4 gcc llvm clang

GCC我有一个 ac 文件,我可以使用如下命令毫无问题地进行编译:

gcc foo.c

但是使用相同的文件我收到在 main 中定义函数的错误clang

clang foo.c

foo:230:1: error: function definition is not allowed here
{
^
foo.c:241:1: error: function definition is not allowed here
{
^
foo.c:253:1: error: function definition is not allowed here
Run Code Online (Sandbox Code Playgroud)

这些错误实例是代码主要部分中新函数的定义。我想知道为什么 GCC 不关心这个问题,而 clang 却关心这个?

Jen*_*ens 5

函数内定义的函数是对 C 语言的扩展,由 gcc 实现。默认情况下启用此功能。如果您使 gcc 成为标准 C 编译器,与-ansi -pedantic-std=C99类似,它也会抱怨嵌套函数定义:

\n\n
x.c: In function \xe2\x80\x98main\xe2\x80\x99:\nx.c:8:5: warning: ISO C forbids nested functions [-Wpedantic]\n     int nested(void)\n     ^\n
Run Code Online (Sandbox Code Playgroud)\n

  • @Jens 嵌套函数有时很有用。例如,我们在 GNU MPFR 中使用它们来支持(可选)日志记录:此类函数是通过函数内部使用的宏扩展来定义的。摆脱嵌套函数意味着拆分宏并确保标识符之间不存在冲突,这将使代码的可读性和可维护性较差。 (10认同)
  • @Jens:嵌套函数类似于 C++ lambda——它们可以访问封闭的函数变量。不过,与 C++ lambda 不同的是,即使它们访问封闭范围,它们也可以转换为简单的函数指针。前者可以通过将函数重新定位到全局作用域并在调用链中传递额外的上下文参数(尽管它很冗长)来完成,后者如果没有编译器对嵌套函数的支持就无法完成。 (6认同)
  • @Jens,“为什么你想要文件范围内的函数?如果你控制源代码,你可以在`main`中重写整个程序,并根据需要使用`goto`来跳转。或者你可以重写汇编中的来源。” 是的...我们是否在编程网站上_认真地_问“当我可以想到方法 Z 以更详细的方式实现类似的结果时,为什么你要用 Y 语言做 X?” (4认同)
  • 谢谢@Jens。你知道这是否也在 clang 中实现了吗? (2认同)
  • @Amir 从 clang 4.0.0 开始,clang 不支持嵌套函数。你为什么想要它们?如果您控制源代码,则可以重写源代码并将嵌套函数移至文件范围。 (2认同)