Starts static's life time really on program execution? - c

Does a static variable really exist for the whole program execution?
I know there is no sense in this code snippet, but I'm asking myself, as I understood the c99 standard,
when I'm getting into the scope of the If statement, It means I never was dereferencing an Object out of its lifetime.
because luckily I was dereferencing the address where the static Object will be/is. So won't this be an undefined behavior as far the if statment is true?
Or does the life time of an static object just begin on its first appearence?
#define UTHOPICALMATCH (int *) 0xBCAA1400
int *foo (void);
int main(int argc, char** argv)
{
int * iPtr = UTHOPICALMATCH;
*iPtr = 5;
if (foo() == UTHOPICALMATCH)
{
printf ("It's still defined behavior!!!\r\n"); // is this true?
/*...*/
return 0;
}
return -1;
}
int *foo (void)
{
static int si;
return &si;
}
EDIT:
In c99 on 6.2.4->3 its said:
An object whose identifier is declared with external or internal linkage, or 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.
So I'm not asking for, its life time after calling foo(), I'm asking my self, does this mean it's valid even before foo() is called?

I am really confused as to what you are asking.
static int * siPtr;
return siPtr;
this means that since siPtr is static, it's initialized to NULL. And because you never modify it, it remains NULL throughout the lifetime of the program. (Yes, it does exist even after foo() returned.)
int * iPtr = UTHOPICALMATCH;
*iPtr = 5;
I don't see what you are trying to do here. UTHOPICALMATCH seems a random hard-coded address, are you sure it's valid?
if (foo() == UTHOPICALMATCH)
printf ("It's still defined behavior!!!\r\n"); // is this true?
It only is if UTHOPICALMATCH is a valid pointer, because then you are just comparing two pointers for equality. Otherwise the behavior is undefined, but that fact has nothing to do with siPtr being static.

Related

Returning pointer to static (outside function) array [duplicate]

This question already has answers here:
Access of static variable from one file to another file
(4 answers)
Closed 4 years ago.
Is the following code "correct"? Or would it be undefined behavior?
// myfile.c
static char x[10][10];
char* my_function() {
return x[0];
}
my_function is being used in a shared library, so I would think it's not safe to access its return value outside the file/compilation-unit (due to the static keyword).
The variable x is not visible by that name outside of myfile.c, however because it resides at file scope, i.e. it has static storage duration, its lifetime is still the lifetime of the whole program.
So it is valid to return a pointer to static data between source files.
This code would not be undefined behavior, in the sense that the pointer to storage of x returned by your function would remain valid even after your function exits. In other words, this does not create the problem that you get when you return a pointer to locally-allocated automatic storage.
A problem you may get by returning this pointer directly is that the callers may not respect the boundaries of x's storage, and access memory past my_function()+sizeof(x). This could be fixed by providing functions to read and write x without returning a pointer to it.
Note: Using static makes the name of the variable x inaccessible, not its storage. The idea is to let other modules define their own variables x without creating a name collision.
There's two different things that 'static' variables do. If you declare a variable as static within a function, then the memory allocated to it within the function remains accessible even after the function returns, example:
#include <stdio.h>
char *func1()
{
static char hello[] = {"Hello, world!\0"};
return hello;
}
char *func2()
{
char goodbye[] = {"Goodbye!\0"};
return goodbye;
}
int main( int charc, char *argv[] )
{
printf( "%s\n", func1() );
printf( "%s\n", func2() );
}
The call to func1() is valid, as the variable "hello" declared inside the function was set as static, so it remains accessible even after the function returns.
The call to func2() is undefined behavior as once the function returns the memory allocated to "goodbye" is returned to the operating system. Generally, you will get a segmentation fault and the program will crash.
The other thing 'static' will do is when a variable (or function) is declared as static at the file level, that variable (or function) will only be accessible within that file. This is for data encapsulation.
So if I have file1.c with the following code:
static *char hello()
{
static char hi[] = {"Hi!\0"};
return hi;
}
And then in file2.c I have:
#include <stdio.h>
extern char *hello(); //This lets the compiler know that I'm accessing a function hello() in another file
int main( int charc, char *argv[] )
{
printf( "%s", hello() );
return 0;
}
If I compile it with
gcc file1.c file2.c -o test
The compiler will complain that it can't find hello().

Returning local static in C

In C language, scope of the static variable through out the file.
In the following code, function returns the static variable.
int fun(){
static int i = 10;
return i;
}
int main() {
printf("%d\n", fun());
return 0;
}
And printed output 10.
So, Is returning local static in C undefined behaviour or well-defined?
You seem to have missed the whole logic for a return statement.
In this snippet, you are actually returning the value (of the variable), so, without the static storage also, the code is fine.
In case, you want to return the address of a variable, it needs to outlast the scope of the function. In that case, you need to have a variable with static storage, so that the returned address is valid (so that it can be used meaningfully from the caller function) even outside the function in which it is defined. So, either
you use a pointer returned by allocator functions, like malloc() or family
use the address of a variable defined with static storage class.

static pointer, initialiser is not constant? [duplicate]

This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 6 years ago.
What I thought static pointer is like other static variables, ones initialised with an value it have same value till end, like that the same address will be held in the static pointer. But in this case the compiler is throwing error
//initialiser element is not constant static int *a = &b[0];
#include <stdio.h>
int main(void)
{
int b[2];
static int *a = &b[0]; // removing static the program works well.
printf("%u",a);
a = &b[1];
printf("%u",a);
return 0;
}
So what is the use of static pointer?
In C, your code doesn't make sense. b has automatic storage duration so conceptually will have a different address each time main is encountered. The static will be initialised only once, and on subsequent invocations of main it may well point to something invalid.
But, and this is the interesting bit, in C++ it ought to make sense since you are not allowed to call main yourself: the behaviour on your doing so is undefined. So the inference of this is that the compiler ought to know that the static is valid for the lifetime of main, and compile the code! Perhaps there is something in the C++ Standard that explicitly forbids this.
In C you are allowed to call main recursively (even implicitly recursively), so the compiler ought to emit an error.
You have two options. Add static to int b[2], or remove it from int *a.
The address of b isn't static. It's variable, because b is a variable with automatic storage.
There may be confusion about static vs const.
Const variables will keep the same value from the time they are initialized until they go out of scope, unless const_cast<> is used, though as #Bathsheba mentioned in comment, use of const_cast<> on a variable declared const is undefined.
Static means it will get initialized at the spot first reaches but then not go out of scope until the end of program execution.

Exact effect of declaring variable inside if block

I am tying to understand the effect of the following in C:
int func(int arg) {
if (arg == 0) {
double *d = malloc(...);
}
//...
}
My understanding is:
Regardless of the value of arg, stack space will be made for the pointer d when func is invoked
d is only initialised, i.e. malloc called, if arg == 0
d can only be accessed inside the if block; trying to access it outside will generate a compile error - even though the stack space for d is allocated regardless.
So, it is equivalent to the following except for the scoping rules that prevent access outside the if block:
int func(int arg) {
double *d;
if (arg == 0) {
d = malloc(...);
}
//...
}
Is this correct? I am compiling with icc default settings which seems to be std=gnu89.
The lifetime of the object denoted by d starts at the beginning of the block in which it is declared (which might be prior to the declaration), not necessarily at the beginning of the function. In practice, compilers may choose to allocate space for all variables at function entry; Gcc, for example, compiles both versions of func to identical assembly. With only a few automatic variables in a function, it's likely that they are all placed in registers and no stack space is used for them at all.
Initialization happens at the point where the initializer appears. All this is subject to the as-if rule (as always): In this case, Gcc doesn't generate any call to malloc when optimizing (and thereby removes the memory leak), a compiler is allowed to "know" what standard library functions do. If this wasn't a library function and the definition not known to the compiler, the call was guaranteed to occur exactly when the initializer is reached.
Using an undeclared identifier (or one that has gone out of scope) is a syntax error, and thus caught at compile-time. The lifetime of the denoted object (with automatic storage duration) ends with the enclosing block, any attempt to refer to it afterwards (through a pointer which used to point to the object) is undefined, no diagnostic required.
In the second code snippet, it's not only syntactically possible to use d after the if block, it's also defined to access the denoted object.
To illustrate the difference between the scope of an identifier and the lifetime of the denoted object, this is valid C99 (and C11) code:
void foo(void) {
int *p = 0;
again:
if(p) {
printf("%d\n", *p); /* n is not in scope here, but the object exists */
*p = 0;
}
int n = 42;
printf("%d\n", n);
if(!p) {
p = &n;
goto again;
}
}
The output is three times 42, when the initializer is reached the second time, n is re-initialized to 42 (and does not stay 0).
Such questions don't arise for C89 (where a label cannot be above a declaration); in GNU89, mixed declarations and code is allowed, though it's not clear to me from the documentation if the C99 rules of lifetime are guaranteed to be honoured.
This code is undefined (in all C standards):
void foo(void) {
int *p = 0;
for(int i=0; i<2; ++i) {
int n = 42;
if(p) { /* (*) */
printf("%d\n", *p);
}
p = &n;
}
}
In the second iteration, p refers to the n of the first iteration, after its lifetime, though both n likely reside at the same storage location, and 42 is outputted. NB, the behaviour is undefined when (*) is reached the second time, reading an invalid pointer is undefined, not only the indirection in the printf call.

Redeclaration of static variables in C... never happens?

I'm trying to fully understand how static variables work in C. I understand that using the static keyword makes the lifetime of the variable equal to the duration of the program. The following example has one thing that confuses me though...
My static_test.c file:
#include <stdio.h>
void foo(){
static int counter = 0;
counter++;
printf("This function has been called %i times.\n",counter);
return;
}
int main(){
int i;
for(i=0;i<10;i++){
foo();
}
return 0;
}
When I first read this example it makes me wonder why the function doesn't print out 0 every time since we are assigning 0 to the static variable.
Is this because once a static variable is declared the compiler ignores another declaration of the same variable on the next calls to my foo() function?
Thanks!
Despite the use of =, this is an initialization, NOT an assignment. So it happens when the variable is initialized and not when the 'statement' is apparently 'executed'. Since it is a static variable, it is initialized once when the program starts, rather than every time the function runs.
Static variables are initialized exactly once at program start, before your function is ever called. The fact that it's a local variable doesn't affect this rule.
In addition, static storage class variables are automatically initialized to zero if not explicitly initialized; the = 0 in your program is superfluous.
From the C11 drafts standard (ISO/IEC 9899:201x), section 6.2.4 Storage durations of objects, paragraph 3:
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.
Yes, the compiler looks for an initial assignment after declaring a static variable and only executes it once, when the program starts.
This only happens when you declare the variable though. For example,
void foo(){
static int counter;
counter = 0;
counter++;
printf("This function has been called %i times.\n",counter);
return;
}
Would print 1 every time.
Static means the variable exists outside of the life time of the function. Think of it as a slightly clever global variable.

Resources