Funciones dentro de funciones en C

Estoy haciendo un código que es similar a esto:

#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; } 

Esto se comstack perfectamente en GCC (sin advertencias) pero no se puede comstackr en ICC.

ICC da:

 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); ^ comstacktion aborted for main.c (code 2) 

¿Qué estoy haciendo mal?

Gracias.

(edit) Perdón por el pobre ejemplo. En mi código original, necesito hacer esto. Estoy usando un integrador numérico GSL y tengo algo así como:

 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); } 

Y tengo muchas funciones con este tipo de estructura: son el resultado de una integración de funciones con muchos parámetros externos. Y las funciones que implementa integración numérica deben recibir un puntero a una función de tipo:

 double f(double x, void * par) 

Realmente me gustaría que las funciones se aniden de esta manera para que mi código no se llene de muchas funciones. Y espero poder comstackrlo con ICC para acelerar un poco las cosas.

Todos los demás te han dado la respuesta canónica “Las funciones anidadas no están permitidas en C estándar” (por lo que cualquier uso de ellas depende de tu comstackdor).

Tu ejemplo revisado es:

 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! } 

Como dices que las funciones como el integrador necesitan

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

No veo por qué realmente necesitas funciones anidadas. Esperaría escribir:

 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); } 

El código anterior debería funcionar en C89 (a menos que haya un problema con la inicialización de ‘par’ como ese) o C99; esta versión del código es solo para C99, utilizando un literal compuesto para el parámetro (sección 6.5.2.5 Literales compuestos):

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

Las posibilidades son excelentes de que tenga solo algunas variaciones en el tipo de ‘parámetros de estructura’. Debe proporcionar nombres separados (suficientemente) significativos para las distintas funciones: solo puede tener una función llamada ‘ f ‘ por archivo fuente.

El único beneficio marginal y minúsculo de la versión de función anidada es que puede estar seguro de que no tiene otra función que la función de llamadas f . Pero dado el código de ejemplo, ese no es un beneficio importante; la definición estática de f significa que ninguna función fuera de este archivo puede llamarlo a menos que pase un puntero a la función.

Las funciones anidadas están disponibles como extensión de idioma en GCC , pero no son parte del lenguaje estándar, por lo que algunos comstackdores no las permitirán.

C no tiene funciones anidadas. Las funciones anidadas de GCC son una extensión del lenguaje.

Su error de tiempo de ejecución en GCC es un error de ortografía. inner_funcion debería ser inner_function .

Como se menciona en muchas respuestas anteriores, las funciones internas no se admiten en C, sin embargo, las clases internas se pueden usar en C ++ para lograr algo similar. Desafortunadamente son un poco difíciles de usar, pero podría ser una opción para ti si no te importa comstackr como C ++.

Ejemplo no probado:

 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; } 

Tenga en cuenta que esta respuesta no debe implicar que creo que las funciones internas son una buena idea en el uso que ha mostrado.

Años después edita:

C ++ ahora nos permite usar lambdas como funciones internas. En el caso de mi ejemplo de juguete anterior, se vería así:

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

Tenga en cuenta que la variable local x se captura automáticamente dentro de la lambda, que es una característica muy agradable.

Más aquí: ¿Qué es una expresión lambda en C ++ 11?

Está utilizando funciones anidadas: C no admite tales cosas.

Ese no es un código C válido, las funciones internas no son compatibles con C

las definiciones de funciones locales dentro de una función son ilegales en C.

Las funciones anidadas no son parte de los estándares de C. Por lo tanto, no hay garantía de que funcione para todos los comstackdores y definitivamente debe evitarse.

En caso de que se esté preguntando cómo desactivar las extensiones de GCC, etc.

Puede usar el indicador -ansi que esencialmente establece el estándar en c89, y desactiva las características del GCC que son incompatibles con ISO C90.

Vea los documentos para más información. Echa un vistazo a la bandera de -std también.

No soy un experto, pero estoy dispuesto a apostar que esto no está explícitamente permitido o indefinido por la especificación C99, por lo que probablemente sea mejor mantenerse alejado de ella.