-1

I'm somewhat beginner in C++ and I've faced a problem. I have defined a function inside other function and I assumed that the variables defined in fun1 is just like global variables to fun2; but the compiler says this is not defined in this scope! Is there a way to have some variables that can be passed to fun2 but not to the main or other functions?

Here is the example that returns error:

double fun1(double,double);
int main()
{
    double z,x=1.0,y=2.0;       
    z=fun1(x,y);
    printf("z=%f",z);
    return 0;
}
double fun1(double x, double y)
{
    double fun2(void);
    double q=5.0,w=7.0;
    return x*q+y*fun2();
}
double fun2()
{
    return w;
}   
  • 1
    `defined a function inside other function`...where? how? why? – Sourav Ghosh Feb 20 '15 at 11:36
  • 3
    Just FYI, Nested functions are not allowed in standard C. – Sourav Ghosh Feb 20 '15 at 11:37
  • you need to define `fun2()` inside `fun1()`. otherwise declare `fun2()` as global. – Himanshu Feb 20 '15 at 11:38
  • 1
    @SouravGhosh mostly why? What is the use case: 1. Of a global variable? 2. Of your sample code? – Iharob Al Asimi Feb 20 '15 at 11:38
  • 1
    @mohammadhmontazeri please show us the actual code. Kindly don't make us feel suddednly we lost our eyesight. – Sourav Ghosh Feb 20 '15 at 11:40
  • @iharob because it's how the standard is ;) no, really, the point was that C was supposed to be minimal, and with little ambiguity. So nested functions where not considered to be important enough to be included in the standard. GCC supports them since what feels like forever, though. – Marcus Müller Feb 20 '15 at 11:42
  • @MarcusMüller Thanks for the information, but I don't think I was asking about that. – Iharob Al Asimi Feb 20 '15 at 11:47
  • @iharob: um, you were asking SouravGhosh "mostly why", who stated "FYI, nested fs are not allowed in std C", and I didn't have the brains to read Sourav's prior comment :D – Marcus Müller Feb 20 '15 at 11:49
  • @SouravGhosh: yes C doesn't support and I've compiled it just as c++. sorry for the mistake. and this is just like the code I want and I prefer defining so many functions like fun2() and pass all of the variables defined in fun1 to them. – mohammadh montazeri Feb 20 '15 at 11:49
  • 1
    @mohammadhmontazeri: I'm certain this is *not* the code you want, because it doesn't work. So your statement is wrong. Also, when calling functions, the scope of the caller is not part of the function's scope -- that is a thing that C does not allow, and which can't work with fully compiled non-symbolic languages as C. What you want is impossible in C. It's as simple as that. – Marcus Müller Feb 20 '15 at 11:50
  • 2
    C does not do what you want it to do. Declaring a function in another does not make variables in that function visible to the function declared. – Spikatrix Feb 20 '15 at 11:51
  • @MarcusMüller I was asking why about the first comment, which has three questions, I am wondering why the **** the OP wants to do that. – Iharob Al Asimi Feb 20 '15 at 11:53
  • @iharob OP is under the misconception that he can, like in some scripting languages, just use variables from the calling scope when he has a nested function, which is impossible, because that's not how C works – Marcus Müller Feb 20 '15 at 12:08
  • @MarcusMüller I didn't know that other languages allowed that, since I never needed such a thing. – Iharob Al Asimi Feb 20 '15 at 12:14
  • @iharob: in python you can do something like that, but that can only work because python interprets the names each time you use the nested function -- which can only work on languages where variable names are not compiled away. – Marcus Müller Feb 20 '15 at 15:54

2 Answers2

3

The problem:

return w;

w is unknown in fun2, change to:

#include <stdio.h>

double fun1(double, double);

int main(void) /* void main is wrong */
{
    double z, x = 1.0, y = 2.0;       

    z = fun1(x, y);
    printf("z=%f\n", z);
    return 0;
}

double fun1(double x, double y)
{
    double fun2(double);
    double q = 5.0, w = 7.0;

    return x * q + y * fun2(w);
}

double fun2(double w)
{
    return w; /* Nonsense but it works */
}   

You can also use a function-like macro:

#include <stdio.h>

double fun1(double, double);

int main(void)
{
    double z, x = 1.0, y = 2.0;       

    z = fun1(x, y);
    printf("z=%f\n", z);
    return 0;
}

#define fun2() (w)

double fun1(double x, double y)
{
    double q = 5.0, w = 7.0;

    return x * q + y * fun2();
}

Nested functions are supported as an extension in GCC:

#include <stdio.h>

double fun1(double, double);

int main(void)
{
    double z, x = 1.0, y = 2.0;       

    z = fun1(x, y);
    printf("z=%f\n", z);
    return 0;
}

double fun1(double x, double y)
{
    double q = 5.0, w = 7.0;

    __extension__ double fun2(void)
    {
        return w;
    } 

    return x * q + y * fun2();
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • thanks, but this is a simple sample and in the original code I have tens of variables in fun1 that must pass into tens of functions like fun2. so passing through arguments is not desirable – mohammadh montazeri Feb 20 '15 at 11:52
  • 3
    @mohammadhmontazeri use a `struct`. And passing through arguments is always desirable, global variables are almost always a bad Idea. – Iharob Al Asimi Feb 20 '15 at 11:53
  • @mohammadhmontazeri, then `w` must be declared as global or better yet (as pointed out by iharob) embedded into a `struct`. – David Ranieri Feb 20 '15 at 11:53
  • Why did you declare `fun2` inside `fun1`? Wouldn't the compiler emit a warning? – Spikatrix Feb 20 '15 at 11:57
  • @CoolGuy, no, it's legal, old C style but still legal. – David Ranieri Feb 20 '15 at 11:59
  • as SouravGhosh said, this is called nested function(I didn't know its name before!) and I want to have fun2 only for fun1. Other scopes of code must not be allowed to use fun2 by mistake. – mohammadh montazeri Feb 20 '15 at 12:02
  • This is not a nested function, is old C style, a nested function is a function (not a prototype) inside another function, gcc supports [nested functions](https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html) as an extension. – David Ranieri Feb 20 '15 at 12:03
  • @mohammadhmontazeri It's *not* a nested function, as I explained: It *declares* there's a function that has the given signature. Doesn't actually define the function. – Marcus Müller Feb 20 '15 at 12:10
  • @AlterMann: I copied the 2nd code you sent and it return error:"test3.cpp:19:5: error: a function-definition is not allowed here before ‘{’ token" in compilation with g++! – mohammadh montazeri Feb 20 '15 at 12:25
  • sorry; I checked and it worked with gcc (as standard c) but it is interesting that it doesn't work with c++ – mohammadh montazeri Feb 20 '15 at 12:28
  • `g++` does not implement nested functions, take a look to [Simulating nested functions in C++](http://stackoverflow.com/questions/5356050/simulating-nested-functions-in-c). – David Ranieri Feb 20 '15 at 12:29
0

It seems you have declared double fun2(void); inside fun1. That's nothing functionally - it just tells the compiler "hey, there's fun2, which takes nothing (void) and returns double. The function as is stays undefined.

You should place that declaration right after your declaration of fun1, right at the beginning.

Of course, a function is a function! Which means, that it takes input to compute output. Using the variables as defined in the function-calling scope is the opposite of what C functions are supposed to be, ie. encapsulating a functionality, without messing with the calling environment.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94