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.
Related
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.
I've been running into a minor problem with regards to seeing people, currently helping a teacher out through grading, and seeing people declaring functions within the scope of main, instead of within the global scope, as I was taught to do, I understand that this still works in itself, but I am kind of confused as to what happens with these functions, should a function be called, that was declared in main, in another function that is not declared inside said main, would this in itself work, and if it does, why. Isn't the function within only the scope of main, and as such shouldn't it remain local to it, or dies C just allocate the space in memory for the functions call at a global scope from the time it is declared, and subsequently defined? Know I was rambling a bit on this, trying to cover all possible questions within this scope.
Sample of what I mean.
int main(){
void foo(int bar);
int boo;
foo(boo);
return 0;
}
void foo(int bar){
...
}
The point that I was trying to stress is that the functions are usable due to the fact that they are related, through main if that makes any sense, but should a function be declared on the global scope such as
#include <stdio.h>
void roo(void);
int main(){} //Holds the same syntax as above with the function declared within it.
//Function foo is same as defined prior.
//Then function roo is defined but uses foo within itself.
void roo(void){
int boo;
foo(boo);
...
}
Shouldn't the codes being compounded, not work fully since the function roo technically has no way to access the function within the scope of main?
edit --
I somewhat saw a point that main would be, with the current lack of multiple functions to be called, would still be at the time used to call function roo, but should this contain multiple functions then wouldn't it be kind of weird or not syntax legal to call up foo from within roo, if it were scaled about 6 functions outside from main.
Declarations are needed for type checking and linking. They exist at compile-time only - they don't actually create an "object" (such as a function body) that exists in any way in the compiled program - all they do is put a name on it, so that other parts of the source can refer to that object without having it immediately to hand. Definitions create objects, but declarations create names.
Going through your example:
void roo(void); // roo becomes visible
int main(){ // main is defined, AND becomes visible
void foo(int bar); // foo becomes visible
foo(6);
roo();
} // foo is no longer visible
void foo(int bar){ /**/ } // foo is defined AND becomes visible
void roo(void){ // roo is defined, but was already visible
foo(6); // so this has no effect on other functions
}
roo can be called from any code in the program below where it was declared, because its name has been put in global scope and is visible from all nested scopes. The following code is aware that somewhere (no idea where), a function called roo exists and is available for use.
Moving down into main, a new scope is opened, and foo made visible within it. main uses this information to call to foo. It uses the information in the global scope to call to roo. The scope closes with the end of main and foo ceases to be visible to the following code; it is not aware that any such function exists.
foo is the simultaneously defined and declared in the global scope. All following code is aware that a function called foo is available for use.
Similarly for roo.
The only places anything is given space in memory are at the three points of definition. None of the declarations cause anything to be allocated, statically or otherwise. All they do is make the code aware of an allocation elsewhere (to be resolved by the linker).
So to (what I think was) the original point of confusion: main calls roo, and roo calls foo, but the declaration of foo in main is not visible to roo. (It sounds like you're confusing static and dynamic semantics: C has static scope only.)
This isn't a problem, because main doesn't know the content of roo, and doesn't need to know its content (some compilers perform inlining; we don't care about that). Control leaves the body code of main and goes to a different point in the program. The body of a function is a black box to every other function; what happens within the code of roo is completely unknown to every other function. roo also doesn't inherit the scope of main, so it has no knowledge of anything that was declared at that time (globally, locally, or otherwise) - it uses the scope opened and closed by its own body further down for name lookups. In that scope, foo has already been declared globally (it inherits the global scope at a separate fixed point on the page), so roo can see foo of its own accord.
Each function exists in one (and exactly one) place. All declarations do is make that place visible to the code that uses it. Code that doesn't use it, doesn't need to be able to see it. main can't see the nested call to foo, so any declaration at that point isn't relevant to it.
New EE with very little software experience here.
Have read many questions on this site over the last couple years, this would be my first question/post.
Haven't quite found the answer for this one.
I would like to know the difference/motivation between having a function modify a global variable within the body (not passing it as a parameter), and between passing the address of a variable.
Here is an example of each to make it more clear.
Let's say that I'm declaring some functions "peripheral.c" (with their proper prototypes in "peripheral.h", and using them in "implementation.c"
Method 1:
//peripheral.c
//macros, includes, etc
void function(*x){
//modify x
}
.
//implementation.c
#include "peripheral.h"
static uint8 var;
function(&var); //this will end up modifying var
Method 2:
//peripheral.c
//macros, includes, etc
void function(void){
//modify x
}
.
//implementation.c
#include "peripheral.h"
static uint8 x;
function(); //this will modify x
Is the only motivation to avoid using a "global" variable?
(Also, is it really global if it just has file scope?)
Hopefully that question makes sense.
Thanks
The function that receives a parameter pointing to the variable is more general. It can be used to modify a global, a local or indeed any variable. The function that modifies the global can do that task and that task only.
Which is to be preferred depends entirely on the context. Sometimes one approach is better, sometimes the other. It's not possible to say definitively that one approach is always better than the other.
As for whether your global variable really is global, it is global in the sense that there is one single instance of that variable in your process.
static variables have internal linkage, they cannot be accessed beyond the translation unit in which they reside.
So if you want to modify a static global variable in another TU it will be have to be passed as an pointer through function parameter as in first example.
Your second example cannot work because x cannot be accessed outside implementation.c, it should give you an compilation error.
Good Read:
What is external linkage and internal linkage?
First of all, in C/C++, "global" does mean file scope (although if you declare a global in a header, then it is included in files that #include that header).
Using pointers as parameters is useful when the calling function has some data that the called function should modify, such as in your examples. Pointers as parameters are especially useful when the function that is modifying its input does not know exactly what it is modifying. For example:
scanf("%d", &foo);
scanf is not going to know anything about foo, and you cannot modify its source code to give it knowledge of foo. However, scanf takes pointers to variables, which allows it to modify the value of any arbitrary variable (of types it supports, of course). This makes it more reusable than something that relies on global variables.
In your code, you should generally prefer to use pointers to variables. However, if you notice that you are passing the same chunk of information around to many functions, a global variable may make sense. That is, you should prefer
int g_state;
int foo(int x, int y);
int bar(int x, int y);
void foobar(void);
...
to
int foo(int x, int y, int state);
int bar(int x, int y, int state);
void foobar(int state);
...
Basically, use globals for values that should be shared by everything in the file they are in (or files, if you declare the global in a header). Use pointers as parameters for values that should be passed between a smaller group of functions for sharing and for situations where there may be more than one variable you wish to do the same operations to.
EDIT: Also, as a note for the future, when you say "pointer to function", people are going to assume that you mean a pointer that points to a function, rather than passing a pointer as a parameter to a function. "pointer as parameter" makes more sense for what you're asking here.
Several different issues here:
In general, "global variables are bad". Don't use them, if you can avoid it. Yes, it preferable to pass a pointer to a variable so a function can modify it, than to make it global so the function can implicitly modify it.
Having said that, global variables can be useful: by all means use them as appropriate.
And yes, "global" can mean "between functions" (within a module) as well as "between modules" (global throughout the entire program).
There are several interesting things to note about your code:
a) Most variables are allocated from the "stack". When you declare a variable outside of a function like this, it's allocated from "block storage" - the space exists for the lifetime of the program.
b) When you declare it "static", you "hide" it from other modules: the name is not visible outside of the module.
c) If you wanted a truly global variable, you would not use the keyword "static". And you might declare it "extern uint8 var" in a header file (so all modules would have the definition).
I'm not sure your second example really works, since you declared x as static (and thus limiting its scope to a file) but other then that, there are some advantages of the pointer passing version:
It gives you more flexibility on allocation and modularity. While you can only have only one copy of a global variable in a file, you can have as many pointers as you want and they can point to objects created at many different places (static arrays, malloc, stack variables...)
Global variables are forced into every function so you must be always aware that someone might want to modify them. On the other hands, pointers can only be accessed by functions you explicitely pass them to.
In addition to the last point, global variables all use the same scope and it can get cluttered with too many variables. On the other hand, pointers have lexical scoping like normal varialbes and their scope is much more restricted.
And yes, things can get somewhat blurry if you have a small, self contained file. If you aren't going to ever instantiate more then one "object" then sometimes static global variables (that are local to a single file) work just as well as pointers to a struct.
The main problem with global variables is that they promote what's known as "tight coupling" between functions or modules. In your second design, the peripheral module is aware of and dependent on the design of implementation, to the point that if you change implementation by removing or renaming x, you'll break peripheral, even without touching any its code. You also make it impossible to re-use peripheral independently of the implementation module.
Similarly, this design means function in peripheral can only ever deal with a single instance of x, whatever x represents.
Ideally, a function and its caller should communicate exclusively through parameters, return values, and exceptions (where appropriate). If you need to maintain state between calls, use a writable parameter to store that state, rather than relying on a global.
What are the differences between static and external variables? What are the advantages of making a static variable?
Why do we prefer making external variables in multifunction programs? The book says that else it gets initialized very late. I don't get it.
Problem is that in C static can have different meanings. I will try to give an overview of the different situations in the following paragraphs.
If a variable is defined outside a function, it can be used by all functions in the file. Sometimes also called 'global variable'. This means that there is only one instance of this variable for the whole file. Also the name of the variable is stored in the resulting .OBJ file. This latter is important, since if another file also defines a variable with the same name outside a function, the linker assumes that it's the same variable in both cases, and merges them.
To make this extra clear, it's best to add the keyword "extern" to one of the variables. In this case, we say that we declare the variable, instead of defining it. It is an extra signal for the compiler/linker to indicate that we actually want to refer to a global variable defined somewhere else.
If you want to define a global variable, but don't want to make it available to other files, add the keyword static before. The keyword static tells the compiler that the variable name must not be stored in the .OBJ file. This means that two .C files with the following line:
static long MyGlobalVariable;
will each have their own variable. Both variables will be called MyGlobalVariable.
If you define a variable inside a function, it becomes a local variable. It comes into existence if the function is called, and disappears again after the function is finished.
In some situations you want to keep the value of the variable in between function calls. You could do this by using a global variable (instead of a local variable) but then the variable becomes available for all functions in the file, which you don't necessarily want. In that case you can put the keyword static before the variable, like this:
void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}
The first time the function is called, MyLocalVariable will be 'created' and initialized with the value 0. At the end of the function, the variable is not destroyed, but kept. So the next time you call this function, the value of the variable will be 1, not zero.
In C it really doesn't matter whether you put the variable outside the function (as global variable) or define it as static inside the function. The only difference is where the variable can be accessed.
In C++, things are quite different. If you write this (outside a function):
MyClass MyGlobalVariable;
MyGlobalVariable will be constructed (this is: the constructor will be executed) at the start of the application, before even main is called. However, you don't have real control over the order in which all global variables are constructed.
So if another file contains this:
MyOtherClass MySecondGlobalVariable;
You can't know for sure whether MyGlobalVariable or MySecondGlobalVariable is constructed first. This can give problems if the constructor of one of them relies on the presence (construction) of the other one.
On the other hand, if you define the variable as static inside a function:
void MyFunction()
{
static MyClass MyStaticVariable;
}
Then MyStaticVariable will be constructed the first time the function is called. With this construction, you can write something like this:
MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}
And we have implemented a singleton where we have control on when it is constructed. The first time we need it, it's constructed.
To be honest, this approach is a rather simplistic one, because it may lead to problems in multi-threaded applications. In that case, there are other tricks.
"Static" more or less means "this will always exist". Depending on the context, you get different results:
static int global_variable;
void function()
{
static int global_function_variable;
}
class foo
{
static void function()
{
static int foo_function_variable;
//...
}
static int foo_variable;
}
global_variable - Only ever visible within the "translation unit". (Since headers are more or less copied in, does this mean a static global in a header exists as separate variables for all cpp files it's included in?)
global_function_variable is created the first time function is called, and will continue to exist throughout the program's lifetime. The value persists, so if you change it in one function call, the next function call will use the changed variable.
foo::function() is a function that can be called like a global function; you don't need to have an instance of foo to call it. This means it doesn't have a valid this pointer, however. Similarly, foo_variable exists even when there aren't any foo objects. All foo objects have the same foo_variable - if you change it in one object, all other objects "see" the change.
foo_function_variable behaves, I think, just like global_function_variable.
The basic idea behind extern is to control the linkage of a variable:
From MSDN :
// specifying_linkage1.cpp
int i = 1;
void other();
int main() {
// Reference to i, defined above:
extern int i;
}
void other() {
// Address of global i assigned to pointer variable:
static int *external_i = &i;
// i will be redefined; global i no longer visible:
// int i = 16;
}
extern int global_variable;
extern can also be used to link a variable using another language, most commonly, C.
global_variable is the most common usage of extern; it says that elsewhere, there's a variable called "global_variable", and we're going to be using that variable. Somewhere, you need to declare the variable without the extern keyword, or it is never actually created.
How can I declare and define a function so that it is only accessible from a single function? I can declare a function in another function. But since local function definitions are illegal (according to Visual C++) I must define the function at global scope, making it possible for other functions to call it.
void f1() {
void f1_private();
f1priv();
}
void f1_private() {
}
void f2() {
f1_private(); // Legal
}
Is it possible to make f1_private only accessible from f1? If not, what are the uses for locally declared functions?
You can put both functions into a single separate file and make the one you want to be less visible static. A static function in C is only accessible from the same source file in which it was declares (sort of a poor-man's namespace concept).
You then just expose the visible function in your header files as you'd normally do.
The best you can do is to put the two functions in their own file, and declare the "private" one to have static linkage (by prefixing the declaration with the word 'static'). Functions with static linkage are accessible only withing their compilation unit (usually meaning the same file, in most build systems).
If the non-private function has to be called from elsewhere, you would then have to either write its prototype in each file it is called from, or create a header file containing the prototype which is included in each file it is called from.
No.
But you can write in C++, declare method inside class, make method private, and make another class friend of first class.
Put a comment on it.
//For use only by foo.
If someone is really gung-ho about using it, they will find a way despite your best efforts. Even if it means just copying and pasting the code, or refactoring the code. The best thing to do is let them know they shouldn't.
You can also encapsulate it by making it private, if it's in a class. Or static if it isn't.
// at the bottom of your .c file
static void foo()
{
}
void dude()
{
// foo only accessible here, unless you have forward
// declared it higher up in the file
foo();
}
However, note that even static methods can be called outside file scope through a function pointer.
You can declare a separate class, with a public member for one function, and a private member function for the one you want only accessible from the other. If this is only used within a class you can make it an internal class.