C中函数内部的函数

我正在制作一个与此类似的代码:

#include  double some_function( double x, double y) { double inner_function(double x) { // some code return x*x; } double z; z = inner_function(x); return z+y; } int main(void) { printf("%f\n", some_function(2.0, 4.0)); return 0; } 

这在GCC中完美编译(没有警告)但无法在ICC中编译。

ICC给出:

 main.c(16): error: expected a ";" { ^ main.c(21): warning #12: parsing restarts here after previous syntax error double z; ^ main.c(22): error: identifier "z" is undefined z = inner_function(x); ^ compilation aborted for main.c (code 2) 

我究竟做错了什么?

谢谢。

(编辑)抱歉这个可怜的例子。 在我的原始代码中,我有点需要做这些事情。 我正在使用GSL数值积分器,有类似的东西:

 double stuff(double a, double b) { struct parameters { double a, b; }; double f(double x, void * params) { struct parameters p = (struct parameters *) params; double a = p->a, b = b->b; return some_expression_involving(a,b,x); } struct parameters par = {a,b}; integrate(&f, &par); } 

我有很多这种结构的函数:它们是函数与大量外部参数集成的结果。 并且实现数值积分的函数必须接收指向类型函数的指针:

 double f(double x, void * par) 

我真的希望函数以这种方式嵌套,所以我的代码不会膨胀很多很多函数。 我希望我能用ICC编译它以加快速度。

其他人都给了你规范的答案“标准C中不允许使用嵌套函数”(因此任何使用它们都取决于你的编译器)。

您修改后的示例如下:

 double stuff(double a, double b) { struct parameters { double a, b; }; double f(double x, void * params) { struct parameters p = (struct parameters *) params; double a = p->a, b = b->b; return some_expression_involving(a,b,x); } struct parameters par = {a,b}; return integrate(&f, &par); // return added! } 

既然你说积分器等function需要

  double (*f)(double x, void * par); 

我不明白为什么你真的需要嵌套函数。 我希望写:

 struct parameters { double a, b; }; static double f(double x, void *params) { struct parameters p = (struct parameters *) params; double a = p->a, b = b->b; return some_expression_involving(a,b,x); } double stuff(double a, double b) { struct parameters par = { a, b }; return integrate(f, &par); } 

上面的代码应该在C89中工作(除非像初始化’par’那样存在问题)或C99; 此版本的代码仅适用于C99,使用参数的复合文字(第6.5.2.5节复合文字):

 double stuff(double a, double b) { return integrate(f, &(struct parameters){a, b}); } 

很有可能你只对“结构参数”类型有一些变化。 您需要为各种函数提供单独的(足够)有意义的名称 – 每个源文件只能有一个名为“ f ”的函数。

嵌套函数版本唯一的微不足道的好处是你可以确定没有其他函数比stuff调用f 。 但鉴于示例代码,这不是一个主要的好处; f的静态定义意味着除非传递指向函数的指针,否则此文件外的任何函数都不能调用它。

嵌套函数在GCC中作为语言扩展提供 ,但它们不是标准语言的一部分,因此一些编译器不允许它们。

C没有嵌套函数。 GCC的嵌套函数是该语言的扩展。

GCC中的运行时错误是拼写错误。 inner_funcion应该是inner_function

正如上面的许多答案所提到的,C中不支持内部函数,但是内部可以在C ++中用于完成类似的事情。 不幸的是,它们使用起来有点笨拙,但如果您不介意编译为C ++,它可能是您的选择。

未经测试的例子:

 double some_function( double x, double y) { struct InnerFuncs { double inner_function(double x) { // some code return x*x; } // put more functions here if you wish... } inner; double z; z = inner.inner_function(x); return z+y; } 

请注意,这个答案不应该暗示我认为内部函数在您显示的用法中是个好主意。

几年后编辑:

C ++现在允许我们使用lambdas作为内部函数。 对于我上面的玩具示例,它看起来很像这样:

 double some_function( double x, double y) { auto inner_function = [&]() { return x * x; } double z; z = inner_function (); return z + y; } 

注意局部变量x是在lambda内部自动捕获的,这是一个非常好的function。

更多信息: C ++ 11中的lambda表达式是什么?

您正在使用嵌套函数 – C不支持此类操作。

这不是有效的C代码,C中不支持内部函数

函数内的局部函数定义在C中是非法的。

嵌套函数不是C标准的一部分。 因此,无法保证它适用于所有编译器,并且绝对应该避免。

如果您想知道如何关闭GCC扩展等。

您可以使用-ansi标志,它基本上将标准设置为c89,并关闭与ISO C90不兼容的GCCfunction。

有关更多信息,请参阅文档 。 查看-std标志。

我不是专家,但我愿意打赌这是C99规范明确禁止或未定义的,所以最好远离它。