Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functions inside functions in C [duplicate]

Tags:

c

function

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.

like image 322
Rafael S. Calsaverini Avatar asked Jun 05 '09 19:06

Rafael S. Calsaverini


People also ask

Can you put a function inside a function in C?

Nested function is not supported by C because we cannot define a function within another function in C.

Can you have a function inside a function?

If you define a function inside another function, then you're creating an inner function, also known as a nested function. In Python, inner functions have direct access to the variables and names that you define in the enclosing function.

Can two functions have the same name in C?

No. In strict C, you cannot do overloading.

What is nesting of function in C?

A nested function is a function defined inside the definition of another function. It can be defined wherever a variable declaration is permitted, which allows nested functions within nested functions. Within the containing function, the nested function can be declared prior to being defined by using the auto keyword.


2 Answers

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.

like image 84
joshdick Avatar answered Oct 05 '22 08:10

joshdick


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.

like image 27
Jonathan Leffler Avatar answered Oct 05 '22 09:10

Jonathan Leffler