How we can access auto and static variables outside their scope in C? - c

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).

Related

How do static variables in C persist in memory?

We all know the common example to how static variable work - a static variable is declared inside a function with some value (let's say 5), the function adds 1 to it, and in the next call to that function the variable will have the modified value (6 in my example).
How does that happen behind the scene? What makes the function ignore the variable declaration after the first call? How does the value persist in memory, given the stack frame of the function is "destroyed" after its call has finished?
static variables and other variables with static storage duration are stored in special segments outside the stack. Generally, the C standard doesn't mention how this is done other than that static storage duration variables are initialized before main() is called. However, the vast majority of real-world computers work as described below:
If you initialize a static storage duration variable with a value, then most systems store it in a segment called .data. If you don't initialize it, or explicitly initialize it to zero, it gets stored in another segment called .bss where everything is zero-initialized.
The tricky part to understand is that when we write code such as this:
void func (void)
{
static int foo = 5; // will get stored in .data
...
Then the line containing the initialization is not executed the first time the function is entered (as often taught in beginner classes) - it is not executed inside the function at all and it is always ignored during function execution.
Before main() is even called, the "C run-time libraries" (often called CRT) run various start-up code. This includes copying down values into .data and .bss. So the above line is actually executed before your program even starts.
So by the time func() is called for the first time, foo is already initialized. Any other changes to foo inside the function will happen in run-time, as with any other variable.
This example illustrates the various memory regions of a program. What gets allocated on the stack and the heap? gives a more generic explanation.
The variable isn't stored in the stack frame, it's stored in the same memory used for global variables. The only difference is that the scope of the variable name is the function where the variable is declared.
Quoting C11, chapter 6.2.4
An object whose identifier is declared [...] with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
In a typical implementation, the objects with static storage duration are stored either in the data segment or the BSS (based on whether initialized or not). So every function call does not create a new variable in the stack of the called function, as you might have expected. There's a single instance of the variable in memory which is accessed for each iteration.

Where is the local static variable stored? If it is data segment, why its scope is not whole program?

If static local variable also stored in the data segment, why can't values are not persist for variable which is used in two different functions. example like this.
void func()
{
static int i=0;
i++;
}
void func1()
{
i++; // here i is stored in the data segment,
// then the scope should be available for entire program
}
Why the value 'i' is only accessible to block scope if is stored in data segment? it might be a silly question but I am trying to understand to concept. Please help me to understand concept. Thanks in advance.
You need to differentiate between the scope and the lifetime of a variable.
In simple words:
"scope" means the region of your source code where the variable is known to the compiler. If a variable is (by the rules) not visible to the compiler, it will refuse to compile accesses to it.
"lifetime" means the time beginning with the allocation of memory for the variable until the moment the memory is assigned to another variable or released. A static variable lives as long as the program runs. A non-static variable lives just as long as its scope is in control.
However, just because both scope and lifetime of a variable are "finished", that does not mean that the memory disappears. The physical cells are still there, and they keep their last contents. That's why you can program functions that return a pointer to some local variable, and retrieve that variables contents after both the scope and the lifetime of the variable are gone. This is a fine example of a beginner's confusing issue.
Consider a compiler for an embedded processor like the 8051. Granted, a quite old and simple machine, but a good example. This compiler will commonly put local variables in its data segment. But to use the limited memory space (128 bytes in total, including working registers and stack) the same memory locations are re-used for variables with non-overlapping lifetimes. Eventhough, you could access any memory from all of the program.
Now, language lawyers, start picking on me. ;-)
A variable in C consists of two things:
A name, called an identifier. An identifier has a scope, which is a region of the program source code in which it is visible (may be used).
A region of storage (memory), called an object. An object has a lifetime, which is a portion of program execution during which memory is reserved for it. This is also called storage duration.
For a variable declared inside a function, its identifier has block scope, and the identifier is visible only from its declaration to the } that closes the innermost block it is in. (A block is a list of statements and declarations inside { and }.)
Inside a function, declaring a variable with static makes its object have static storage duration, causing it to exist for all of program execution, but it does not change the scope of its identifier. The object exists throughout program execution, but the identifier is visible only inside the function.
When another function is called, the object still exists (and it can be used if the function has its address, perhaps because it has been passed as a parameter). However, the identifier for the variable is not known inside the source code of other functions, so they cannot use the identifier.

Is function pointer address always static?

If a function pointer scopes out before being used in another thread to run, will the pointer be invalid? Or are function pointers always valid since they point to executable code which doesn't "move around"?
I think my real question is whether what the pointer points to (the function) will ever change, or is that value static throughout lifetime of program
Pseudo-code:
static void func(void) { printf("hi\n"); }
int main(void)
{
start_thread();
{
void (*f)(void) = func;
// edit: void run_on_other_thread(void (*f)(void));
run_on_other_thread(f); // non-blocking.
}
join_thread();
}
In the C base language, the values of function pointers never become invalid. They point to functions, and functions exist for the entire time a program is executing. The value of a pointer is valid for the entire program.
An object that contains a pointer may have a limited lifetime. (Note: The question mentioned scope, but scope is where in the source code an identifier is visible. Lifetime is when during program execution an object exists.) In the question void (*f)(void) = func;, f is an object with automatic storage duration. Once execution of the block it is defined in ends, f no longer exists, and references to it have undefined behavior. However, the value that was assigned to f is still a valid value. For example, if we define int x = 37;, and the lifetime of x ends, that does not mean you can no longer use the value 37 in a program. In this case, the value that f had, which is the address of func, is still valid. The address of func can continue to be used throughout the program’s execution.
The situations discussed in Xypron’s answer regarding dynamically linked functions or dynamically created functions would be extensions to the C language. In these situations, it is not the lifetime of the pointer object that is in question but rather the fact that the function itself is being removed from memory that causes the pointer to be no longer a valid pointer to the original function.
Whether a function pointer remains valid depends on its usage.
If it points to a function in the source code of your process it stays valid during the runtime of the process.
If you use a function pointer to point to a function in a dynamic link library, the pointer becomes invalid when unloading the library.
Code can be written that relocates itself. E.g. when the Linux kernel is started it relocates itself changing the addresses of functions.
You could call a runtime compiler which creates functions in memory during program execution possibly reusing the memory when an object goes out of scope.
As said it depends.

Is it correct to call a static variable local?

It is known that the C language supports two kinds of memory allocation through the variables in C programs:
1) Static allocation is what happens when you declare a static
variable. Each static variable defines one block of space, of a fixed
size. The space is allocated once, when your program is started, and
is never freed.
2) Automatic allocation happens when you declare an automatic
variable, such as a function argument or a local variable. The space
for an automatic variable is allocated when the compound statement
containing the declaration is entered, and is freed when that compound
statement is exited.
(this is a full quote from http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html)
The question is: is it correct to call a static variable in a function "local" in terms of memory allocation and why?
Thanks to everyone in advance.
P.S. any quotes from the C standard are welcome.
C standard doesn't define the term of local variable. Automatic and static refer to storage duration.
C11 (n1570), § 6.2.4 Storage durations of objects
An object has a storage duration that determines its lifetime.
You could call it a "function-local static variable" or something like that, but if you simply call it a "local variable" you may find that people are surprised when they find out it's actually static, and therefore has some of the properties of a global variable.
There are two types of static variables in C.
The global static variables, where the static states that these variables can only be seen in this translation-unit.
Static variables with a local scop (i.e. in function). These are initialized once and keep their value event after going out of scope.
And to you question: no, a variable can't be static and automatic at the same time.
If you check their addresses, you will se that the static variable does not live on the current stack frame.
In the context of variables, the term local most often denotes visibility and scope rather than the storage mechanism and lifetime.
Using the term local variables in C is in fact inaccurate as the standard never talks about that.
Informally, a static variable inside a function could be said to be local within the visible scope of the function, but not much more than that.
I would suggest against using the term local variables at all. Instead, one should talk about static variables within a function, automatic variables, static variables in the file scope and globals.
The question is: is it correct to call a static variable in a function "local" in terms of memory allocation and why?
Static variables are stored in the data section of the memory allocated to the program.
Even though if the scope of a static variable ends , it can still be accessed outside its
scope , this may indicate that , the contents of data segment , may be independent
of scope.
Example
#include <stdio.h>
int increment(void);
int main()
{
printf("\ni = %d",increment());
printf("\ni = %d",increment());
printf("\ni = %d",increment());
}
int increment(void)
{
static int i = 1;
return i++ ;
}
In the above example , after each function call to increment() , the static variable i inside the function goes out of scope every time the function returns but persistently
retains its value. This is only possible because the variable is not on the same same stack as the function , but it is present entirely in a different memory area , the data segment.

using static keyword in C local scope to function

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.

Resources