11

看下面的代码,我在另一个函数中定义了一个函数,

void test1(void)
{
 void test2(void)
 {
   printf("test2\n");
 }
 printf("test1\n");
}

int main(void)
{
 test1();
 return 0;
}

这种用法很奇怪,是 c89/c99 的用法还是只是 gcc 的扩展(我在 ubuntu 12 编译时使用了 gcc 4.6.3)。我运行这段代码,它输出“test2”和“test1”。test2 只能在 test1 中调用。

还有,这个用法的常见场景是什么,或者这个用法是做什么用的?

4

4 回答 4

18

是的,这是一个GCC 扩展

它不是 C,它不是可移植的,因此除非你知道 GCC 会

  • 成为唯一用于构建代码的编译器
  • 将在未来版本中继续支持此功能
  • 不要在意最小惊讶原则
于 2013-05-16T08:40:22.217 回答
4

正如所写,它不是合法的 C++。但是,您可以在函数中定义一个类,并在该类中定义函数。但即便如此,在 C++11 之前,它仍然只是词法嵌套;您定义的类不会“捕获”外部函数的任何上下文(除非您明确实现捕获);在真正的嵌套函数中,嵌套函数可以访问外部函数中的局部变量。在 C++11 中,您 可以定义具有自动捕获功能的 lambda 函数。

C 和 C++ 从未采用嵌套函数的原因是 ,为了使捕获起作用,您需要额外的信息,结果导致指向函数的指针变得更加复杂。结果是您不能获取嵌套函数的地址(缺乏正交性),指向嵌套函数的指针与指向函数的普通指针不兼容(最终需要太多外部细节才能计算出来),或者所有指向函数的指针都有额外的信息(并且您为大部分时间不使用的东西付费)。

于 2013-05-16T08:52:36.960 回答
2

http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_5.html#SEC71

嵌套函数解释。

于 2013-05-16T08:40:21.403 回答
0

嵌套函数仅在 C 中允许,但很少使用,因为它们仅在该函数范围内可见。但是,如果您想解决嵌套函数,您可以执行以下操作

#include<stdio.h>
typedef void (*fptr)(void);
fptr test1(void) {
    void test2(void) {
        printf("test2\n");
    }
printf("test1\n");
return test2;
}
int main(void) {
    void (*f)(void);
    f = test1();
    f();
    return 0;
 }
于 2013-05-16T09:17:05.047 回答