C generating random values for int variables [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Default values of int when not initialized in c. why do i get different outputs?
Beginner so be lil soft..am compiling a simple code below, I am not assigning any value to my variables but C program generates some random values, why is it so?(Only 2nd variable generates random integers)
So where these values came from?
#include<stdio.h>
main(void) {
int var1;
int var2;
printf("Var1 is %d and Var2 is %d.", var1, var2);
return 0; //Book says I should use this for getting an output but my compiler anyways compile and return me values whether I use it or not
}
//Output 1st compiled: var1 = 19125, var2 = 8983
//Output 2nd compiled: var1 = 19125, var2 = 9207
//Output 2nd compiled: var1 = 19125, var2 = 9127

Your C program is compiled to some executable program. Notice that if you compile on Linux using gcc -Wall, you'll get warnings about uninitialized variables.
The var1 and var2 variables get compiled into using some stack slots, or some registers. These contain some apparently random number, which your program prints. (that number is not really random, it is just unpredictable garbage).
The C language does not mandate the implicit initialization of variables (in contrast with e.g. Java).
In practice, in C I strongly suggest to always explicitly initialize local variables (often, the compiler may be smart enough to even avoid emitting useless initialization).
What you observe is called undefined behavior.
You'll probably observe a different output for var1 if you compiled with a different compiler, or with different optimization flags, or with a different environment (probably typing export SOMEVAR=something before running again your program could change the output for var1, or running your program with a lot of program arguments, etc...).
You could (on Linux) compile with gcc -fverbose-asm -S and add various optimization flags (e.g. -O1 or -O2 ...) your source code yoursource.c and look inside the generated yoursource.s assembler code with some editor.

In C, when you declare variables, that reserves some space for them on the stack. The stack is how C keeps track of which arguments are passed to which function, where variables are stored if you declare them statically within function, where return values are stored, and so on. Each time you call a function, it pushes values on the stack; that is, it writes those values to the next available space on the stack, and updates the stack pointer to account for this. When a function returns, it decrements the stack pointer, to point to where it pointed in the previous function call.
If you declare a variable, but you don't initialize it, you simply get whatever value was in there before. If another function has been called, you may get the arguments passed in to that function; or you might get the return address for the function you are returning to.
In the case that you present, you are showing the main() function, with no other functions called. However, in the process of loading your program, the dynamic linker has probably called several functions within your process space. So the values that you are seeing are probably left over from that.
You cannot depend on what these values are, however. They could be anything; they could be initialized to 0, they could be random data, they could be any sort of internal data.

The content of var1 and var2 are undefined. Thus, they can contain any valid value (depending on many external factors).
It is pure luck that only the second var seams to be random. Try it on another day, after a reboot or after launching a few other programms and I bet the first var will have changed.

It's called local variables . Any local variables have auto storage specifier and these are located on stack in C.
Since you havn't initilaized these varaibles , so it will take any value called garbage value or indeterminate value (Language standard doesn't imposes any requirements that it must have specific value ) so you are getting any random value.
It's purely coincedence that you are getting same value for var1 but not for var2.
But on any other system it might give different values or even on your system may after sometime.
So,Using uninitialized variables is undefined behaviour

In C,
If the variables are declared as Global or static, then they are automatically initialised to zero. But, if they are declared as local , then the values for those variables are indeterminate i.e .., depends on the compiler. (Some garbage value)

Related

What happens to initialization of static variable inside a function

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

Is a C compiler obligated to always reload const value from memory?

I have a const variable in my embedded C program. It's defined and initialized with 0 in program code. It's placed in a special ROM area via linker script. One can change the content of the special area via special programming procedure, but it cannot be changed during main program execution.
The question is whether I have to declare the constant as volatile. If it's not marked as volatile, is the compiler allowed to replace all references to it with 0? Or is it obligated to load it at least once during program execution?
It looks like your variable is really a constant (i.e. doesn't change during program execution) with a value unknown to the compiler. If this is the case, you can declare it like this:
extern const int variable;
(i.e. without volatile and without an initializer) and let the linker script or other tools set up the correct value.
The compiler will then be permitted to load it and potentially leave it in a register forever, but not replace it by 0 or any other value at compile time.
If marked as volatile the compiler is obliged to load it from memory every time it needs it value.
If not marked as volatile, the compiler may load it once from memory, store it in a register, and use this register instead of loading it again.
A not-optimizing compiler may do this - but it also may, stupidly, load it every time. (As not reloading is in fact an optimization in itself.)
Optimizing compilers may notice the const and decide it can be compiled with its real, literal value; up to a point where the original constant does not appear at all in the .data section of your program. (Or maybe it does but it never gets "read".)
Since you change the value in a linker script, the compiler cannot "know" the value got changed after compiling. In that case, use volatile: the only way to tell the compiler not to trust that the value is known when compiling.

Does gcc initializes auto variable to 0?

Why am i getting 0. I is an auto variable, so it should print some garbage value, right? I am using gcc compiler.
#include "stdio.h"
void main() {
int i;
printf("%d\n", i);
}
Does gcc initializes auto variable to 0?
Yes and No!
Actually uninitialized auto variables get indeterminate value (either an unspecified value or a trap representation1).
Using such variables in a program invoke undefined behavior-- behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which ANSI C International Standard imposes no requirements. (C11:ยง3.4.3)
Once UB is invoked you may get either expected or unexpected result. Result may vary run to run of that program, compiler to compiler or even version to version of same compiler, even on temperature of your system!
1. An automatic variable can be initialized to a trap representation without causing undefined behavior, but the value of the variable cannot be used until a proper value is stored in it. (C11: 6.2.6 Representations of types--Footnote 50)
No, I get random values with gcc (Debian 4.9.2-10) 4.9.2.
ofd#ofd-pc:~$ gcc '/home/ofd/Destkop/test.c'
ofd#ofd-pc:~$ '/home/ofd/Desktop/a.out'
-1218415715
ofd#ofd-pc:~$ '/home/ofd/Desktop/a.out'
-1218653283
ofd#ofd-pc:~$ '/home/ofd/Desktop/a.out'
-1218845795
Variables declared inside a function are uninitialized. One cannot predict what might show up if you print them out. in your example main is a function too. Hence it so happens that it is zero.
When you declare variable to be static or gloabally, the compiler will have them initialzed to zero.
It has become standard security practice for freshly allocated memory to be cleared (usually to 0) before being handed over by the OS. Don't want to be handing over memory that may have contained a password or private key! So, there's no guarantee what you'll get since the compiler is not guaranteeing to initialize it either, but in modern days it will typically be a value that's consistent across a particular OS at least.

What is the difference between volatile & extern?

Few days back i had an interview but, still I am searching for the answer.
I would like to understand the significance of using volatile keyword.
Find the code below: Two different scenario.
//project1
//File1.c
int abc;//Global variable
/*And this variable is getting used in some other files too.*/
if(abc == 3) //Say
{
printf("abc == 3");
}
else
{
printf("abc != 3");
}
/*So if or else part will not be optimized
because "abc" can not be predicted,
the value can chage at any point of time */
//Project2
//file1.c
volatile int abc;//Global variable with volatile keyword
/*And this variable is getting used in some other files too.*/
if(abc == 3) //Say
{
printf("abc == 3");
}
else
{
printf("abc != 3");
}
/*So if or else part will not be optimized
because "abc" can not be predicted as it is declared as volatile,
the value can chage at any point of time */
Why we should use volatile keyword instead?
As Tony Delroy explained in its comment, extern and volatile are quite different.
Volatile keyword protects your variable from being aggressively optimised. An optimised variable can be invisible to other threads and never reach main memory. Sometimes, compiler can even squeeze entirely a variable if it's not needed. Compiler base its guess with your source code as its only input. Sometimes, there is some external events which can change your variable value. It could be an hardware device or an other process, for instance.
=> Concretely, compiler disables some optimisations to this variable, so it can behave as you want it to.
Extern is not about cache vs memory. Extern is just about accessing a variable which lives in an other object files. See this short example of what kind of assembly code is generated for an extern access.
Those extern variables are optimised in their own object file as far as it's possible. There's no question about to protect it or not.
=> Concretely, compiler indicates an external reference needing to be solved at link time
volatile in declaration or prototype say always load/store value from/to memory regardless local, static or extern this vlaue (but in case of local it is not always meaningful).
Also using volatile keyword in regular source are untypically. It is useful only for hardware which map hardware registers to memory (like in ARM architecture), in special cases of kernel/driver development.
If you use volatile in GUI or ecommerce code you probably wrong...
volatile usually means one or more of the following:
The variable may get changed by another OS thread
The normal flow of execution in the program may be interrupted by a signal and the signal handler might change the variable
The normal flow of execution is running a loop, the variable is being read within the loop, and the variable is changed by means of point 1 or 2
volatile means that throughout the lifetime of the program there are two (or more) reads R1 and R2 of the variable, and some other event happening inbetween R1 and R2 will change the variable outside of the normal flow of execution.
extern means that the variable has been defined somewhere elsewhere and that the program is reusing that definition.
I don't quite agree with the previous answers so here are my two cents.
By declaring a variable volatile you're telling the compiler that its value can change at any time and that it cannot make any assumptions about the variable's value, not even in two consecutive (assembler) instructions. In consequence any use of the variable must be done by accessing the actual variable and not a cached value.
In the code you provided there is no behavioural difference between abc being global, extern or volatile because if()/else only evaluates the variable once. There is a difference however if you change the else by a second if, as in:
if(abc == 3)
{
printf("abc == 3");
}
if (abc != 3)
{
printf("abc != 3");
}
If abc is NOT declared volatile, the compiler may optimize the second if and replace it by an else statement, in consequence abc would only be read and evaluated once, meaning either the first xor the second prints will be executed (but not both and also not none).
If abc IS declared volatile (no matter if local, global or extern), the compiler is forced to evaluate abc twice because its value could have changed in between. This means that any of the two prints, or both, or none, may be executed.
Extern is a different story entirely. All it does is tell the compiler that the variable has been defined in another file (whose address will be provided at link time). If the compiler can predict that the value of abc won't change between the two if statements (it doesn't matter how the compiler might be able to), then it may still optimize the second if into an else and reduce the two abc evaluations to one.
Essentially, volatile is used to indicate that a variable's value will be modified by different threads.
Declaring a volatile Java variable means:
The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory";
Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
Extern essentially means that all modules can use the defined variable.

Declaring a function level static variable inside an if block that is never hit

My understanding about static variables declared inside a function is:
If no initial value is specified, the static variable will reside in .bss, otherwise in .data
The memory for statics are allocated along with globals - i.e., well before the execution enters main
are these two assumptions correct ?
When the execution hits the function for the first time, statics are initialized to the user specified value (or zero in case no initial value is specified).
...and they retain their values across subsequent invocations of the function
But what if I declare my static variable inside an if block? I assume my third point should be updated to "when the execution hits the line where the static variable is declared, they're initialized to ... " - am I right ?
Now, what if the if block in which they're declared is never hit (and the compiler is able to figure this out) - I understand that the variable will never be initialized; but does any memory get allocated for that variable?
I wrote two functions to try to figure out what's happening:
#include <stdio.h>
void foo()
{
static foo_var_out;
if(0){
static foo_var_in_0;
printf("%d %d\n", foo_var_in_0);
} else {
static foo_var_in_1;
printf("%d %d\n", foo_var_in_1);
}
}
static void bar(int flag)
{
static bar_var_out;
if(flag){
static bar_var_in_0;
printf("%d %d\n", bar_var_in_0);
} else {
static bar_var_in_1;
printf("%d %d\n", bar_var_in_1);
}
}
int main()
{
foo();
bar(0);
}
And I took the object dump:
$ gcc -o main main.c
$ objdump -t main | grep var
45:080495c0 l O .bss 00000004 foo_var_in_1.1779
46:080495c4 l O .bss 00000004 foo_var_out.1777
47:080495c8 l O .bss 00000004 bar_var_in_1.1787
48:080495cc l O .bss 00000004 bar_var_in_0.1786
49:080495d0 l O .bss 00000004 bar_var_out.1785
From the output it looks like foo_var_in_0 was not created at all (presumably because it is inside an explicit if(0)), whereas bar_var_in_0 was created (as it is possible for the caller to pass a non-zero value - although the only caller is explicitly passing zero).
I guess my question is: is it correct to assume that no memory was allocated for the variable foo_var_in_0 at all? I am asking about this specific case; am I reading the objdump correctly - or should I be doing something more to verify if the variable will take some memory while the program is ran?
In other words, if the line that declares a function level static variable is never hit, is the variable actually declared at all?
If it will not be created at all, is this according to the C standard (less likely), or a compile time optimization and at what level - how do I turn it ON/OFF (in gcc 4.1.1)?
I understand that one int is not a big deal to care about, but I am more interested in how it works; also, what if the variable was a big array of size, say 5000 elements of a 10 byte struct?
is it correct to assume that no memory was allocated for the variable foo_var_in_0 at all?
No, I don't think it would be correct to assume that. As far as I know, optimizations like this are not part of the standard.
If you know for a fact that you compiler does this and you want to assume it, go ahead. If you write anything that needs this to be the case, you might want to write a post-build test to make sure that it happened.
Probably, what you are seeing is a side-effect of the compiler just pruning out some code that it knew would never run. Meaning, it's not specifically looking to remove statics, but it did remove an entire branch, so any code in it just got removed as well.
The C standard does not prescribe where to place variables and stuff. It just prescribes that a conforming implementation shall have equivalent behaviour (to a reference behaviour which is specified by the standard), where "equivalent" is also defined by the standard.
So the simple answer is that it is an optimization, and how to turn it on/off depends on the particular compiler.
An implementation that does interprocedural analysis would probably be able to get rid of bar_var_in_0 as well.
Just to add to the correct answers from the others. Your assumptions about initialization of static variables are not correct.
Variables with static storage are
always initialized. Either explicitly
if you provide an initializer or
implicitly from 0.
The initializer for such a variable
must always be a compile time
constant expression. So the value is
computed at compile time and written
directly into the object. (Well if it
is all zero, some systems have tricks
/ special sections that avoid an
explicit storage of the variable in
the object file.)
So, no, there will be no initializer
statement run when the variable is
accessed the first time (how would
the system know, by the value of
another static variable?) but whenever
you start the program the variable is
already initialized.

Resources