GNU C编译器包含一个称为Nested Functions的C语言扩展,但其中一些点在文档中不够清晰。例如,它说:
如果模块中没有其他对
通过存储其地址或将地址传递给另一个函数,可以从其名称范围之外调用嵌套函数。
如果在包含函数退出后通过其地址调用嵌套函数,则会出现问题。
如果在包含作用域级别退出后尝试调用它,并且它引用了不再在作用域内的某些变量,则您可能很幸运,但冒险并不明智。
然而,如果嵌套函数不引用任何已超出范围的内容,则应该是安全的。
因此,一方面,它说如果在包含函数退出后调用嵌套函数,“将会出现问题”,但是在几句话之后,它说有情况可以这样做。
我想他们所谓的“超出范围的内容”是自动变量,因此特别是重构应该是安全的。
static int f() { ... }
int outer() {
... // some use of f
}
进入
int outer() {
int f() { ... } // f does not refer to outer's local variables
... // some use of f
}
如果模块中没有其他对
f
的使用,除了在outer
函数中,即使假设outer
函数以某种方式泄漏f
地址超出其自身范围。
然而,我惊讶地发现以下代码无法编译
int main(void) {
void nested_function(void) {}
static const struct { void (*function_pointer)(void); } s = {
.function_pointer = nested_function
};
return 0;
}
这个投诉是说初始化元素不是常量
(即nested_function
)。
这个限制有什么原因吗?(我无法想象一个函数的地址是非常量的,即使它是嵌套的)