Why is there a compile error in this code? - c

I was trying to understand the difference between closures and function pointers, and I came across this answer in SO
What I don't understand is this code
BOOL (*lessThanTest)(int);
int lessThan = 100;
lessThanTest = &LessThan;
BOOL LessThan(int i) {
return i < lessThan; // compile error - lessThan is not in scope
}
Why there is a compile error consideringn that lessThan is a global variable, it can be accessed from within LessThan function, did I miss something?
EDIT
This is not my code, it's taken from an answer in SO Function pointers, Closures, and Lambda

Closures take all the variables in their lexical scope along for the ride, possibly extending their lifetimes. Function pointers don't -- if the variables referenced inside their code disappear, they're hosed.
The code example you've given is a little bit confusing. I believe that it's meant to be inside of a function, meaning that lessThan is a local variable. If that scope is exited, but the function pointer still exists, then its code would have a reference to a non-existent variable -- lessThan.

You missed a paragraph in that answer:
But, now I have to pass the 2 arguments when I evaluate it. If I wished to pass this function pointer to another function where lessThan was not in scope, I would either have to manually keep it alive by passing it to each function in the chain, or by promoting it to a global.
In what you posted, int lessThan is not meant at global scope, it should be assumed to be in a function somewhere.

Well, no, if lessThan is global, it shouldn't produce compile error, though you can hardly tell by this fragment what is meant to be where. lessThanTest=&LessThan; is definitely from some local scope, for instance.

This code has some problems:
You declare lessThanTest as an uninitialized function pointer
You can't assign something to it later under global scope
You're using LessThan before declaring it.

Related

Accessing global structs in C functions

My understanding is that C functions only work with copies of variables unless passed by address. However, the following appears to work OK, and I am confused as to why. I am accessing a global struct in a function and it appears to change the global value even though I am not passing the address.
Global struct:
cal{
int a;
int b;
}cal;
Function:
AlterCalAandCalB()
{
cal.a = 1;
cal.b = 2;
}
This appears to change the global variable not just inside function.
I rewrote the code to this, and the performance is identical:
AlterCalAandCalB(struct cal *ptrCal)
{
ptrCal->a = 1;
ptrCal->b = 2;
}
I am interested in learning the best practice, not just what works. I realize that global variables are not recommended but in this particular case it works for me. But I want to learn the best practice for pointers.
My understanding is that C functions only work with copies of variables unless passed by address.
That's slightly confused. C functions receive their arguments by value -- roughly speaking, they receive copies, including if the argument is the address of an object or function. This is about argument passing, not about the behavior of the statements in function bodies.
Every executable statement is inside a function body. There would be no point to "global" variables if functions could not share access to them.
I am interested in learning the best practice, not just what works.
Best practice is a matter of opinion, so it is off topic here. But note that if you are going to pass the address of an object to all functions that you want to access it (excluding main(), I suppose), then there is no point to declaring that object at file scope in the first place.

C calling nested function inside another nested function

When I call a trampoline nested function inside another nested function, the trampoline nested function doesn't have access to the trampoline variables, in this case the float, r.
typedef void (*callback)();
callback Wrapper(float r) {
auto void foo();
void foo() {
// do something with r.
}
return &foo;
}
int main(void)
{
callback c = Wrapper(0.1);
auto void foo2();
void foo2() {
c(); // doesn't work unless i don't use r in foo (Segmentation fault (core dumped))
}
foo2();
c(); // works fine.
return 0;
}
From gcc documentation nested functions:
If you try to call the nested function through its address after the containing function exits, all hell breaks loose.
The function void foo is defined inside function Wrapper and the address to the function foo is returned from Wrapper. Then you call the function after the function Wrapper exits. As documentation states your code makes "all hell break loose".
Think of a nested function as a variable allocated on stack. When the function returns, the nested function stops existing.
the trampoline nested function can't access to the trampoline variables, in this case the float r.
The variable r has scope only within Wrapper function. Once Wrapper exits, the variable r stops existing.
auto void foo();
auto void foo2();
That's odd. There's no need to write that. Just write the function - it's like auto by default anyway.
You cannot use c() once Wrapper() has finished, because it is out of scope. Think of it as if that function existed only while Wrapper() was being executed (even if you know that it's code is still somewhere, you cannot execute it for the reasons explained below, if it is not from the inside of the function that contains it) You call Wrapper() in the beginning of main(), and Wrapper() returns a pointer to a function that is local to Wrapper(). Well, that pointer is a fake pointer because the function has ceased to exist as soon as the program returned from Wrapper. This is like returning a pointer to a local variable.
I should say Undefined Behaviour, but as we are talking about a GCC extension, that term is out of scope also, so what can I say then? (As I have seen from the other answer by KamilCuk, GNU uses the term all hell breaks loose, which sounds perfect for me)
The implementation of nested functions means using displays (arrays of pointers to the closest active call records of all the nested functions out of this one, this is done in other languages, like Pascal, Ada or Modula-2) to access the scoped identifiers in outer functions, like you do, when you access the float r from c(), but later, when Wrapper is not being executed, no display exists of the local variables in Wrapper() and the call to c() is in error because the access to the value 1.0 has gone long ago.
For all purposes, your trick to try to call c() out of scope (outside of Wrapper()) is illegal, and I don't know why can you require this, but you are wrong if you thought you can maintain a local resource (like the parameter r in Wrapper, after the call to the function that used it has return)
I suggest you to have a look to the array of nested function pointers and how the compiler access to variables on the outer function through the display, by looking at the assembly code of the nested functions (you can nest indefinitely, and at each level of nesting you add one more pointer to the vector) In standard C there are no displays, because all the functions are defined at top level.

Functions that call each other, declared inside another function

I have two functions that call each other, inside of another function:
int main(){
void aaa();
void b(){
aaa();
}
void aaa(){
b();
}
aaa();
}
(Yes, this example would be stuck in an infinite loop or cause a stack overflow)
The compiler throws the error: static declaration of 'aaa' follows non-static declaration
If I move the function declarations outside of the other function, it works (but I can't do that because those functions need to have access to main's local variables)
Is it possible to make this work?
C does not support nested functions, nor closures.
One solution for your actual problem is to define the shared state (the local variables of main you mentioned, in this case) as struct, then have variable of this struct type, and pass it as pointer to the functions that use it.
You don't show the local variable code in your question, so I'm not writing and arbitrary example. Please edit the question with more code, if you want an example.
Another solution is to just use global (preferably static) variables, used both from other functions and main. I mean, since main isn't a normal function (can't be called recursively by standard, for example), its local variables end up being unique objects anyway, so this is just a matter of scope and visibility, with little to no funcional difference.

access Pointers in C programming

I'm new to programming, and am trying to get a better understanding of pointers specifically. Could a static variable be declared inside a function and then accessed or deferenced from outside the function? Why would you not allow explicit pointers to it out of scope, since the memory of the static variable would remain allocated.
Could a static variable be declared inside a function and then accessed or deferenced from outside the function?
The language allows it. So, yes, you can access a pointer to it from outside the function and dereference the pointer from outside the function.
Why would you not allow explicit pointers to it out of scope, since the memory of the static variable would remain allocated.
There are risks associated with that. A calling function can change the state of the static variable. That may or may not be OK depending on the overall structure of your program.
Could a static variable be declared inside a function and then accessed or deferenced from outside the function?
Yes, you can do that.
Explain the scenario where you need this, but in general I don't think its a good approach. Just declare it global.
That question was part of a Homework in Programming 101 when I was in college :)

Static functions and variables in C

I know what is the purpose of using static variables in an object oriented language, still, I don't understand what is the meaning of using the "static" keyword in C.
Can someone explain it to me?
On a function or global variable, static makes the function or global variable local to that file; other files cannot access that function or global variable by that name (but they can access it if you give a pointer to it away).
On a local variable, it makes it act as if it was a global variable, but is only accessible within that function (unless, again, you give a pointer to it away).
The value that a static variable has upon leaving a function is the same value that variable will have the next time the function is called.
A static function can be called only from within the same file that the function appears.

Resources