Functions inside functions in C [duplicate]
I'm making a code that is similar to this:
#include <stdio.h>
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;
}
This compiles perfectly in GCC (with no warnings) but fails to compile in ICC.
ICC gives:
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)
What am I doing wrong?
Thanks.
(edit) Sorry for the poor example. In my original code I kinda need to do this stuff. I'm using a GSL numerical integrator and have something like:
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);
}
And I have lots of functions with this kind of structure: they are the result of an integration of a functions with lots of external parameters. And the functions that implements numerical integration must receive a pointer to a function of type:
double f(double x, void * par)
I would really like functions to be nested this way so my code doesn't bloat with lots and lots of functions. And I hope I could compile it with ICC to speed things a bit.
Solution 1:
Nested functions are available as a language extension in GCC, but they are not part of the standard language, so some compilers will not allow them.
Solution 2:
Everybody else has given you the canonical answer "Nested functions are not allowed in standard C" (so any use of them depends on your compiler).
Your revised example is:
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!
}
Since you say that the functions such as the integrator need
double (*f)(double x, void * par);
I don't see why you really need nested functions at all. I would expect to write:
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);
}
The code above should work in C89 (unless there's an issue with initializing 'par' like that) or C99; this version of the code is for C99 only, using a compound literal for the parameter (section 6.5.2.5 Compound literals):
double stuff(double a, double b)
{
return integrate(f, &(struct parameters){a, b});
}
The chances are excellent that you have only a few variations on the 'struct parameters' type. You do need to provide separate (sufficiently) meaningful names for the various functions - you can only have one function called 'f
' per source file.
The only marginal, tiny benefit of the nested function version is that you can be sure that no other function than stuff
calls f
. But given the example code, that is not a major benefit; the static definition of f
means that no function outside this file can call it unless passed a pointer to the function.
Solution 3:
C doesn't have nested functions. GCC's nested functions are an extension to the language.
Your runtime error in GCC is a spelling error. inner_funcion
should be inner_function
.