Is there any difference in these two? If so, what exactly is the difference? Assume they are in a C function that may be called multiple times.
declare and assign in same statement
static uint32_t value = x; // x varies and may be passed into function.
declare in one statement and assign in next statment.
static uint32_t value;
value = x; // x varies;
Is value updated only the first time it is declared/initialized or even on subsequent calls.
My understanding of (1) is that it is only set the first time that line is executed so even if x changes the next time the line executes, value will remain the same. I am not sure about (2) but clarification on both will be very helpful
EDIT: Compiler ARM(ADS1.20).
EDIT: A follow up question on (2) from the answers given so far. Is the declaration(not the assignment) repeated on every call or just the first time?
The first should not compile; the static variable requires a constant initializer.
The second sets value each time the function is called, so there was no need to make it static in the first place.
If the first notation was correct - initialized value to 1, say - then it would be initialized once when the program starts and would thereafter only take new values when the code changed it. The second notation still sets value on each call to the function, and so renders the use of static pointless. (Well, if you try hard enough, you can devise scenarios under which the second version has a use for static. For example, if the function returns a pointer to it that other code then modifies, then it might be needed, but that is esoteric in the extreme and would be a pretty bad 'code smell'.)
1 is only executed once, but for 2 value will be reassigned every time.
Static variables are initialized only once.
These are very different declarations.
The first one is declaring a static local variable and giving it an initial value (this should not actually compile given that x is not a constant). This will only occur once before the function is every executed. This is almost certainly the initialization you want.
The second declaration is updating the value every time the function is called. If you want the variable to always start the function with the same value this is the right approach. But if this is truly what you want, then why use a static at all? Just use a local variable.
Your intuition is right. In the second example value is set to x each time the method is called. Static variables need to be initialized and declared in one statement if you only want it to run once.
If you always want value to have the value x, don't declare it as static.
When compiled, the first one will be put into the ".data" section, where data is initialized, while the second one will be put into the ".bss" section, where data is uninitialized.
Use readelf -S xx.o can check the section size of compiled object file.
example 1:
static int i;
void test(){
i = 2;
}
example 2:
static int i=1;
void test(){
i = 2;
}
Folks - In C, the first declaration is perfectly legal. It will compile, and could be used to initialize the value. You could combine the line of code from the second declaration to ensure it gets updated every subsequent function execution. This is commonly used, in particular in embedded programs where memory and resources are more scarce than computers or distributed applications.
The reason why you would use a static is to ensure the variable has a data lifecyle that continues throughout program execution while limiting its access to only the function the static is declared, or any function in the file if the static declaration is on top of the file, otherwise, the data will be lost every time the function is exited. This is good programming practice to avoid inadvertent access to data objects that must be secured and restricted. That comment only applies to the C programming language, don't mistake this to apply for C++ (where it does in some instances), or JAVA. Static in Java has a completely different meaning. From what I've read in this thread, few seem to understand how the keyword static works in C, and are confusing the keyword static form other languages to apply in C. In C, static is a very important keyword that helps manage function and data access, and you can initialize a static variable with another variable provided it is within scope, and you can update that value throughout program execution, which would probably what you need to do anyways.
Related
Auto and static variable have scope limited to the block in which they are defined. Since Auto variables are defined in the stack, if the function exits, stack is destroyed and memory for the auto variable is released. But I read somewhere "However, they can be accessed outside their scope as well using the concept of pointers given here by pointing to the very exact memory location where the variables reside." Is this correct?
Also, static variables are defined in the data section so it retains its existence till end of program. The scope is within the block in which it is defined. Is there any way through which we can access static variable from any other function? Also, Is there any way we can access static variable from any other file?
Here's a very simple example:
void print_msg(const char* msg) {
printf("The message is: %s\n", msg);
}
int main(void) {
char m[] = "Hello, world!";
print_msg(m);
}
Here, m is an automatic variable, which is not in scope in print_msg. But print_msg clearly has access to its value.
Don't confuse "scope" with "lifetime". The scope of a variable is that part of the program where the variable's name is visible (and thus can be used). The lifetime of a value is the period during program execution in which a value exists. Scope is about program text; it relates to compilation. Lifetime is about program execution.
As you said, static variables exist through out the life cycle of the program i.e memory allocated to them is not destroyed as long as the program is running. So, to access such a variable out side its scope, we can pass around the pointer to that memory location via pointer. A small example to show the same
#include <stdio.h>
#include <stdlib.h>
int* func()
{
static int a = 0;
a++;
printf("a in func = %d\n", a);
return &a;
}
int main()
{
int *p;
p = func();
printf("a in main from ptr : %d\n", *p);
*p++;
p = func();
return 0;
}
As you can see in the example, func() returns the pointer to the static variable it has declared, and any one who wishes to access the variable a, can use that pointer. NOTE: we can only do this because static variable's life is through out the program. Now irrespective of the static variable being in a different function or a different file, as long as you can some how get hold of the pointer to that static variable, you can use it.
Now coming to the case of auto variable.
What happens if you run the above program changing a from static to auto?
you will see that while compiling a warning warning: function returns address of local variable [-Wreturn-local-addr] is thrown and when executing, we get a segmentation fault.
What causes this is that the auto variable exists only in its scope, i.e as long as the function func() is being executed, the variable a has memory allocated for itself. As soon as the function exits, the memory allocated for variable a is freed and so the value pointed to by pointer p is at some unallocated memory location (resulting in segmentation fault).
Note, as comments rightly point out, I am making an assumption here, the assumption that the simplest case of calling another function is not what the question is about. This assumption was not (yet) confirmend or rejected by OP. This case is discussed e.g. in the answer by rici.
The existence of auto variables is not only exist to "within" their scope (simplified: only code between the same enclosing {} can use their identifier), they are also restricted to "during" their "chronological scope" i.e. their lifetime (simplified after starting the execution of the code in the function and finishing its execution). It is possible to access the memory location of a variable via a pointer, which was set to their address (which is only possible within their scope, because accessing via their identifier is necessary) as long as it is done during their lifetime, yes.
But how would that pointer be found from anywhere else?
Maybe by being written (from inside their scope and during their lifetime) to a global variable.
But which "other" code should then use that value? (remember I am putting the call of functions at the side here)
This requires multithreading/multitasking/multiwhatevering. Lets say there is an interrupt service routine doing it. It would have to see the same address space as the variables scope, i.e. no memory management units getting in the way with some virtual memory magic. This is not true for many multiwhatevering implementations, but admittedly for a few of them, so lets continue.
This imagined ISR would have to ensure that it only accesses the auto variable while it actually exists (i.e. during its lifetime), otherwise it would pretty much access what is effectively a meaningless random memory location. And this assumes that the ISR is actually allowed/able to access that memory. Even without MMUs, there are implementations which can/will have execeptions.
This introduces the need for synchronisation mechanisms, e.g. semaphores.
So in certain environments it would be possible, but completley pointless (global variables are still involved), expensive, hard to understand and next to impossible to port. (remember I am putting call of a function aside here)
Similar for static variables.
In the case of function local static variables, they would at least reliably exist, but accessing them would still need the pointer value to be somehow transported out of their scope. For static variables that could actually be done via the return value of the function as demonstrated in the answer by yashC.
In the case of "static" variables understood as file scope restricted variables, the pointer still would have to be transported out of the file scope.
This would merely defeat what is probably the point of a file scope restricted variable. But I could imagine some kind of access privilege scheme, as in "Here is the key to the vault. Handle with care."
As mentioned at the start of this answer, I am putting the call of other functions aside. Yes, the easiest way to leave the scope of a function is to call another one. If that other function has a pointer parameter, it can use it to read-access and write-access the auto variable of the calling function. That is the normal case of call-by-reference parameters as supported by C.
Calling a function also provides another, even simpler way of read-accessing the value of an auto variable of the calling function, though not write-accessing and not actually accessing the autovariable itself, only using its value. That way is the trivial mechanism of a call-by-value parameter, it does not even require a pointer. Both ways (call-by-reference parameter and call-by-value parameter) conveniently guarantee that the value does not change during the execution of the called function. (this time I am putting the multi-threaded case aside, because that is discussed in the main part of this answer).
After stumbling onto this question and reading a little more here (c++ but this issue works the same in C/C++ AFAIN) I saw no mention to what is realy happening inside the function.
void f(){
static int c = 0;
printf("%d\n",c++);
}
int main(){
int i = 10;
while(i--)
f();
return 0;
}
In this snippet, c lifetime is the entire execution of the program, so the line static int c = 0; has no meaning in the next calls to f() since c is already a defined (static) variable, and the assignment part is also obsolete (in the next calls to f()), since it only takes place at the first time.
So, what does the compiler do? does it split f into 2 functions - f_init, f_the_real_thing where f_init initializes and f_the_real_thing prints, and calls 1 time f_init and from that onward, only calls f_the_real_thing?
The first assignment is not "obsolete" - it ensures c is zero the first time f() is called. Admittedly that is the default for statics: if no initialiser is specified, it will be initialised to zero. But a static int c = 42 will ensure c has the value 42 the first time the function is called, and the sequence of values will continue from there.
The static keyword means that the variable has static storage duration. It is only initialised once (so will have that value the first time the function is called) but changes then persist - any time the value is retrieved, the value retrieved will be the last stored in the variable.
All the compiler does is place the variable c into an area of memory that will exist - and hold whatever value it was last set to - for as long as the program is running. The specifics of how that is achieved depends on the compiler.
However, I have never seen a compiler that splits the logic of the function into multiple parts to accommodate the static.
Although the standard does not dictate how compilers must implement behavior, most compilers do a much less sophisticated thing: they place c into static memory segment, and tell the loader to place zero into c's address. This way f comes straight to pre-initialized c, and proceeds to printing and incrementing as if the declaration line where not there.
In C++ it optionally adds code to initialize c to static initialization function, which initializes all static variables. In this case, no call is required.
In essence, this amounts to c starting its lifetime before the first call to f. You can think of c's behavior as if it were a static variable outside f() with its visibility constrained to f()'s scope.
The C standard doesn't specify how the required behaviour for static storage duration must be implemented.
If you're curious about how your particular implementation handles this, then you can always check the generated assembly.
(Note that in your particular case, your code is vulnerable to concurrency issues centred around c++ not necessarily being atomic; also its vulnerability to int overflow, although i-- does act as an adequate termination condition.)
(changed name of variable from original question to fit the actual code)
I'm new to C and I'm implementing a queue.
The error is with the static int head=0 variable. It's incremented by 1 each time dequeue() is called. The error seem to occur when the queue is dequeued and function get_person() is called. The head-variable is then as it seems getting a high random number, like 23423449. I have no idea where this comes from. However if I get rid of the "static" keyword so variable is declared as int head=0, it works fine. How come?
using a "global" variable in top of a included file: static int variable1=0
This clearly indicates, that you don't understand what the static keyword means on the global scope. In the global scope, outside of a function, static means, that the variable is visible to only the code within the compilation unit the variable has been defined in.
Now if you define a static variable in a header, each compilation unit that includes that header will have its own variable of that name. So your program is littered with many identically named variables each specific to the compilation unit it's in.
I think what you actually want is an non-static, extern declaration in the header, and exactly one compilation unit actually defining the variable.
I think you are overrunning your person array
One of the strcpy functions is going beyond the bounds of the buffers in the person object, and overwriting the head variable. I would guess the tail and nbr_elem are going too.
You should check that the number of characters you are copying does not exceed the buffer lengths, or use strncpy.
If you declare a global static variable in file A.c, it means this variable is only available within the scope of this A.c file. See : http://en.wikipedia.org/wiki/Static_variable
Since you haven't posted any code, and you are metioning using the same variable in a different file (e.g. B.c), it seems like it is invoking an undefined behavior, which explains the random number your program is printing.
If you wish to use the variable in a different .c file, you should not make it static.
You are calling strcpy without checking that the values you are trying to write will actually fit inside the allocated space inside the person struct.
What is most likely happening is you are writing beyond the allocated memory, and your strcpy is actually overwriting the value of head. strcpy will keep writing until it hits a null terminator ('\0').
If you were to run this in valgrind (a useful tool for finding this type of problem in large programs) it would probably tell you you have invalid writes occurring.
C assumes you know what you are doing, as long as you have access to the memory you can do with it as you please :)
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.
I'm refactoring "spaghetti code" C module to work in multitasking (RTOS) environment.
Now, there are very long functions and many unnecessary global variables.
When I try to replace global variables that exists only in one function with locals, I get into dilemma. Every global variable is behave like local "static" - e.g. keep its value even you exit and re-enter to the function.
For multitasking "static" local vars are worst from global. They make the functions non reentered.
There are a way to examine if the function is relay on preserving variable value re-entrancing without tracing all the logical flow?
Short answer: no, there isn't any way to tell automatically whether the function will behave differently according to whether the declaration of a local variable is static or not. You just have to examine the logic of each function that uses globals in the original code.
However, if replacing a global variable with a static local-scope variable means the function is not re-entrant, then it wasn't re-entrant when it was a global, either. So I don't think that changing a global to a static local-scope variable will make your functions any less re-entrant than they were to start with.
Provided that the global really was used only in that scope (which the compiler/linker should confirm when you remove the global), the behaviour should be close to the same. There may or may not be issues over when things are initialized, I can't remember what the standard says: if static initialization occurs in C the same time it does in C++, when execution first reaches the declaration, then you might have changed a concurrency-safe function into a non-concurrency-safe one.
Working out whether a function is safe for re-entrancy also requires looking at the logic. Unless the standard says otherwise (I haven't checked), a function isn't automatically non-re-entrant just because it declares a static variable. But if it uses either a global or a static in any significant way, you can assume that it's non-re-entrant. If there isn't synchronization then assume it's also non-concurrency-safe.
Finally, good luck. Sounds like this code is a long way from where you want it to be...
If your compiler will warn you if a variable is used before initialized, make a suspected variable local without assigning it a value in its declaration.
Any variable that gives a warning cannot be made local without changing other code.
Changing global variables to static local variables will help a little, since the scope for modification has been reduced. However the concurrency issue still remains a problem and you have to work around it with locks around access to those static variables.
But what you want to be doing is pushing the definition of the variable into the highest scope it is used as a local, then pass it as an argument to anything that needs it. This obviously requires alot of work potentially (since it has a cascading effect). You can group similarly needed variables into "context" objects and then pass those around.
See the design pattern Encapsulate Context
If your global vars are truly used only in one function, you're losing nothing by making them into static locals since the fact that they were global anyway made the function that used them non-re-entrant. You gain a little by limiting the scope of the variable.
You should make that change to all globals that are used in only one function, then examine each static local variable to see if it can be made non-static (automatic).
The rule is: if the variable is used in the function before being set, then leave it static.
An example of a variable that can be made automatic local (you would put "int nplus4;" inside the function (you don't need to set it to zero since it's set before use and this should issue a warning if you actually use it before setting it, a useful check):
int nplus4 = 0; // used only in add5
int add5 (int n) {
nplus4 = n + 4; // set
return nplus4 + 1; // use
}
The nplus4 var is set before being used. The following is an example that should be left static by putting "static int nextn = 0;" inside the function:
int nextn = 0; // used only in getn
int getn (void) {
int n = nextn++; // use, then use, then set
return n;
}
Note that it can get tricky, "nextn++" is not setting, it's using and setting since it's equivalent to "nextn = nextn + 1".
One other thing to watch out for: in an RTOS environment, stack space may be more limited than global memory so be careful moving big globals such as "char buffer[10000]" into the functions.
Please give examples of what you call 'global' and 'local' variables
int global_c; // can be used by any other file with 'extern int global_c;'
static int static_c; // cannot be seen or used outside of this file.
int foo(...)
{
int local_c; // cannot be seen or used outside of this function.
}
If you provide some code samples of what you have and what you changed we could better answer the question.
If I understand your question correctly, your concern is that global variables retain their value from one function call to the next. Obviously when you move to using a normal local variable that won't be the case. If you want to know whether or not it is safe to change them I don't think you have any option other than reading and understanding the code. Simply doing a full text search for the the name of the variable in question might be instructive.
If you want a quick and dirty solution that isn't completely safe, you can just change it and see what breaks. I recommend making sure you have a version you can roll back to in source control and setting up some unit tests in advance.