What is the meaning of "statically allocated"? - c

http://linux.die.net/man/3/pthread_mutex_init
In cases where default mutex attributes are appropriate, the macro
PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are
statically allocated. The effect shall be equivalent to dynamic
initialization by a call to pthread_mutex_init() with parameter attr
specified as NULL, except that no error checks are performed.
I know about dynamic allocation. What is the meaning of "statically allocated"?
My question here is to understand the meaning of "statically" allocated. I posted the quote from the man page to provide a context, only.

Statically allocated means that the variable is allocated at compile-time, not at run-time. In C, this can be a global variable at the file scope or a static variable in a function.
A good overview is found here:
http://en.wikipedia.org/wiki/Static_memory_allocation
Variables on the stack (i.e., local variables in functions that do not have the static keyword) are allocated when the function is called, sometimes multiple times when a function is called recursively. So they are conceptually different from static memory allocation (which only happens once per program).

Related

Can a static initializer macro require dynamic cleanup? (could pthread_mutex_initializer ever require pthread_mutex_destroy?)

I have viewed many other questions regarding this topic and I feel that I am informed on the topic... But there is one aspect to the question that I want to discuss.
As stated here Destroy static mutex and rwlock initializers
(It is not necessary to call pthread_mutex_destroy() on a mutex that was statically initialized using PTHREAD_MUTEX_INITIALIZER.)
However I want to pose a more fundamental question:
If an API provides a macro to initialize an object/type, similar to the PTHREAD_MUTEX_INITIALIZER, then is there anything that macro could expand out to which would REQUIRE a call to a dynamic destructor function?
To clarify what I'm asking:
Is there anything that could be done in the PTHREAD_MUTEX_INITIALIZER that would require a dynamic destructor to cleanup?
Would it be okay to safely assume that if an object/type has a static macro initializer like PTHREAD_MUTEX_INITIALIZER that it is impossible for the macro to initialize anything that would need dynamic cleanup, and therefore it's impossible for pthread_mutex_destroy to ever be necessary for PTHREAD_MUTEX_INITIALIZER?
Or is it possible to change something in the future that may cause PTHREAD_MUTEX_INITIALIZER to do some operation that would absolutely require the pthread_mutex_destroy function to be called?
edit: The only thing I could think of would be to maybe register a gcc __attribute__((constructor)) or something in order to automatically call some code, at which point it's not really a static initialization anymore right? If it was truly a static initialization then that by definition means it cannot do anything dynamic; ergo by definition a static initializer macro couldn't require a dynamic cleanup function, right?
If an API provides a macro to initialize an object/type, similar to
the PTHREAD_MUTEX_INITIALIZER, then is there anything that macro could
expand out to which would REQUIRE a call to a dynamic destructor
function?
In general, yes. A macro can expand to a function call, or to an initializer containing one, which might return a pointer to dynamically allocated space or a structure or union containing such a pointer.
But for PTHREAD_MUTEX_INITIALIZER or any other macro that can be used to initialize a file-scope variable, no. Such initializers must be constructed from constant expressions, and there is nothing such an initializer could contain that would obligate cleanup.
Do note, however, that that's not a complete story. However an object is initialized, there are innumerable ways in which its subsequent use could cause a requirement for releasing resources via a destructor function to adhere to it. In particular, POSIX does not promise that failing to destroy a mutex initialized via the macro will be without consequences. Nor does it draw any distinction between the initial state of a mutex initialized via the initializer macro and the initial state of one initialized via pthread_mutex_init() with default attributes. Either way, resources requiring cleanup could be associated with such a mutex by calls to pthread_mutex_lock(), for instance.
But don't overlook that any "requirement" in this realm is conditional, not absolute. Calling pthread_mutex_destroy() is potentially required in order to achieve a desirable outcome, such as avoiding a resource leak. Not making the call means obtaining a different outcome, which may still be an acceptable one.
Perhaps a good example would be the NULL macro. Any pointer object may be initialized with NULL, which does not have any resource-management implications. If a pointer to dynamically-allocated space is subsequently assigned to it, however, then failing to ever pass that object's value to free() may cause a resource leak. Yet such a leak may be acceptable -- for example, if the allocated space needs to be retained until program termination anyway, then it makes little practical difference whether the program releases it itself, or whether it relies on the OS to handle that as part of cleaning up after the process.
That quote is specific to Linux, and is a consequence of the fact that on linux, pthread_mutex_destroy is essentially a noop. From the manual page:
pthread_mutex_destroy destroys a mutex object, freeing the resources it might hold. The
mutex must be unlocked on entrance. In the LinuxThreads implementation, no resources are
associated with mutex objects, thus pthread_mutex_destroy actually does nothing except
checking that the mutex is unlocked.
Thus on Linux, pthread_mutex_destroy is never required, for any mutex.

How we can access auto and static variables outside their scope in 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).

Check if memory is allocated for temporary arrays across functions

The program has a function A that calls an inline function B.
#define EIGEN_RUNTIME_NO_MALLOC is at top of the program.
If I put Eigen::internal::set_is_malloc_allowed(false); within function A, would that check for memory allocation in both A and B when I call A?
Thanks.
set_is_malloc_allowed(false) is a global function which sets a global flag (More accurately: A static variable inside a global function). Therefore, it will prohibit memory allocations (inside Eigen) until set_is_malloc_allowed(true) is called at any place.
You can check if memory currently is allowed using is_malloc_allowed().

Is it recommended to use Variable Length Array (VLA) with inlined functions in C?

As VLAs are assigned memory on the stack, will they cause any problem if we inlined the function containing them? I think, because of the same behavior of alloca i.e. storing objects on the stack, compilers avoids inlining such functions(?).
Whereas (the nonstandard) alloca function yields an object whose lifetime is the calling function, a VLA's lifetime is the block in which it is declared. However inlining is not relevant to either of them. A function call whose body happens to get inlined is still a function call, and objects it obtains by alloca cease to exist when it semantically returns, not when the cpu executes a ret instruction or equivalent.
I would have thought that any memory assigned to a stack for a VLA (struct you are using) would somehow be a different memory area to that allocated for an inline function. Besides, when the inline code is compiled or interpreted, that would be a job for the processor/parser and not for the stack. So in short, I would say, no.

How the static variable gets retrieved for every function call

We know that when the control exits from function the stack space will be freed. So what happens for static variables. Will they be saved in any memory and retrieved when the function gets called ??
The wiki says:
In the C programming language, static is used with global variables
and functions to set their scope to the containing file. In local
variables, static is used to store the variable in the statically
allocated memory instead of the automatically allocated memory. While
the language does not dictate the implementation of either type of
memory, statically allocated memory is typically reserved in data
segment of the program at compile time, while the automatically
allocated memory is normally implemented as a transient call stack.
and
Static local variables: variables declared as static inside a function
are statically allocated while having the same scope as automatic
local variables. Hence whatever values the function puts into its
static local variables during one call will still be present when the
function is called again.
Yes, static variables persist between function calls. They reside in data section of the program, like global variables.
You can (and probably should) read more about general memory layout of C applications here.
Adding some more information on top of previously given answers -
The memory for static objects is allocated at compile/link time. Their address is fixed by the linker based on the linker control file.
The linker file defines the physical memory layout (Flash/SRAM) and placement of the different program regions.
The static region is actually subdivided into two further sections, one for initial value, and the other for changes done in run time.
And finally, remember that if you will not specify otherwise, the value will be set to 0 during compilation.
You made an incorrect assumption that static variables are placed on the stack* when the function that uses them is running, so they need to be saved and retrieved.
This is not how C does it: static variables are allocated in an entirely different memory segment outside of stack, so they do not get freed when the function ends the scope of its automatic variables.
Typically, static data segment is created and initialized once upon entering the program. After that the segment stays allocated for as long as your program is running. All your global variables, along with the static variables from all functions, are placed in this segment by the compiler. That is why entering or leaving functions has no effect on these variables.
* The official name for "stack" is "automatic storage area".
Consider this example:
static int foo;
void f(void)
{
static int bar;
}
The only difference between foo and bar is that foo has file scope whereas bar has function scope. Both variables exist during the whole lifetime of the program.

Resources