What does printf print for an unitialized variable? - c

What should the code print? 0 or any garbage value or will it depend on the compiler?
#include <stdio.h>
int a;
int main()
{
printf("%d\n",a);
return 0;
}

the answer is 0. Global variables are initialized to zero.

I would say your code might output anything or simply anything can happen because your code invokes Undefined Behaviour as per C99.
You don't have a prototype for printf in scope.
J.2 Undefined behavior
— For call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an ellipsis or the types of the arguments after promotion are not compatible with the types of the parameters (6.5.2.2).
If the question is about initialization of global variables then a would be initialized to 0 because it has static storage duration.

I found on C99 standard, Section 6.7.8.10, Initialization:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.
Section 6.2.4.3 defines:
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.
In other words, globals are initialized as 0. Automatic variables (i.e. non-static locals) are not automatically initialized.

without automatic variable [generally what we use in function in most cases] all other variable's value is assigned to 0

Global variables are initialized as 0. Automatic variables (i.e. non-static locals) are not automatically initialized.

Related

Are thread_local objects initialized to 0 in C?

Are non-local thread storage duration objects initialized to 0 in C?
static thread_local int x; // is x initialized to 0?
The C17 standard says the below (in 6.2.4.4).
An object whose identifier is declared with the storage-class specifier _Thread_local has thread
storage duration. Its lifetime is the entire execution of the thread for which it is created, and its
stored value is initialized when the thread is started.
It does not explicitly say it is initialized to 0. But the C++
standard makes it explicit and says: (in 3.6.2.2)
Variables with static storage duration ([basic.stc.static]) or thread
storage duration ([basic.stc.thread]) shall be zero-initialized
([dcl.init]) before any other initialization takes place
So, does C initialize non-local thread_local objects to 0 or not?
Thread local objects without explicit initialization are initialized to “zero.”
C 2018 7.26.1 3 says thread_local expands to _Thread_local if <threads.h> is included. That is not shown in the question, but presumably it is.
C 2018 6.2.4 4 says “An object whose identifier is declared with the storage-class specifier _Thread_local has thread storage duration…
C 2018 6.7.9 10 says:
… If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
The paragraph ends there; the trailing “;” instead of a period is a typographical error.

Automatic storage duration struct initialization

Some of this may be a duplicate, but I am sorry for that.
Let's say I have this struct:
struct foo
{
int a;
int b;
int c;
};
1. If struct foo type object is declared in the way that it has automatic storage duration and without initializers, is it guaranteed that all it's members will be force initialized to zero?
{
// other stuff
struct foo bar;
// other stuff
}
2. If struct foo type object is declared in the way that it has automatic storage duration and with some initializers, is it guaranteed that members, which are not explicitly initialized, will be force initialized to zero?
{
// other stuff
struct foo bar = {.a = 1};
// other stuff
}
3. If struct foo type object is declared in the way that it has automatic storage duration and by using compound literal expression, is it guaranteed that members, which are not explicitly initialized, will be force initialized to zero?
{
// other stuff
func((struct foo){.a = 1});
// other stuff
}
Any C standard references are much appreciated! Thank you!
Summary, TL;DR:
Storage duration explained:
A variable declared inside a function has automatic storage duration (including parameters to functions).
A variable declared as static, or a variable declared outside functions at file scope ("global") has static storage duration.
Struct (and array) initialization explained:
If you initialize no member and the struct has automatic storage duration, nothing is initialized.
If you initialize no member and the struct has static storage duration, all members are zero-initialized.
If you initialize any member(s), those you didn't touch get initialized to zero.
The relevant part of the C standard (C17 6.7.9 §10):
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:
if it has pointer type, it is initialized to a null pointer;
if it has arithmetic type, it is initialized to (positive or unsigned) zero;
if it is an aggregate, every member is initialized (recursively) according to these rules, and any
padding is initialized to zero bits;
Where "artihmetic type" is standard gibberish for plain variables like int, and "aggregate" is standard gibberish for arrays and structs.
Further down in the same chapter (C17 6.7.9 §19):
...all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.
Answers to your questions:
If struct foo type object is declared in the way that it has automatic storage duration and without initializers, is it guaranteed that all it's members will be force initialized to zero?
No, it is not guaranteed; their values are indeterminate as stated in the first sentence of the quote above.
If struct foo type object is declared in the way that it has automatic storage duration and with some initializers, is it guaranteed that members, which are not explicitly initialized, will be force initialized to zero?
Yes, as per C17 6.7.9 §19 cited above.
If struct foo type object is declared in the way that it has automatic storage duration and by using compound literal expression, is it guaranteed that members, which are not explicitly initialized, will be force initialized to zero?
Yes, since compound literals are arrays or structs, they follow the same initialization rules.
First of all, uninitialized variables with automatic storage will never be initialized. From The C11 standard (ISO/IEC 9899:2011 §6.7.9/10):
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
Then from this structure initialization reference:
All members that are not initialized explicitly are initialized implicitly the same way as objects that have static storage duration.
And if we follow the "initialized implicitly" link we have:
objects with static and thread-local storage duration are initialized as follows
...
objects of integral types are initialized to unsigned zero
...
So to answer your questions:
No, no initialization is done as there is no explicit initialization in your code (see the quote from the standard)
Yes, since this is a structure initialization
Yes, for same reason as 2.
The links provided have references to the standard.

Using an uninitialized global variable (for read and write) is OK?

If I use uninitialized global variable in C program, What happens? Is it undefined behavior?
#include <stdio.h>
int i;
int main()
{
while(i < 5)
{
i++;
}
printf("%d\n", i);
return 0;
}
Is it undefined behavior?
No.
What happens?
i has static storage duration (file scope). It will initialize to zero by default.
TL;DR No, you're fine.
But don't take my word for it, let's also see a bit more on the why part, following the authoritative sources.
First of all, let's see the scopes of the identifiers (variable).
Note:all emphasis mine
As per C11, chapter §6.2.1
If the declarator or type specifier that declares the identifier
appears outside of any block or list of parameters, the identifier has file scope, which
terminates at the end of the translation unit.
Then, from chapter §6.2.2
[...] If
the declaration of an identifier for an object has file scope and no storage-class specifier,
its linkage is external.
and, finally, for the storage class, chapter §6.2.4,
An object whose identifier is declared without the storage-class specifier
_Thread_local, and either with external or internal linkage or with the storage-class
specifier static, has static storage duration.
So, the global variable you mentioned has static storage duration.
Now, you say, it is not initialized explicitly, lets see what the spec has to say about this.
Quoting chapter §6.7.9/P10,
If an object that has static or thread storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules,
and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these
rules, and any padding is initialized to zero bits;
So, the variable has a defined value even without explicit initialization, so using that variable to read is perfectly OK. No undefined behavior here.

What is the default value of char in c

When I declare an int variable, and do not not assign a value to it, and then when I print it, a random number gets printed.
but when I allocate a char variable, and print it with %c format specifier, nothing is printed. So does a char variable in C have a default value like null? Do local variables in C start with a random value? Then why doesn't a char behave in this way?
There is no default value which is assigned to it. Some values are not printable and you can assume that random value is one of them, so that is the reason why you are not able to see the result.
The C99 standard says that:
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.
On a side note:
As per C99
If an object that has static storage duration is not initialized
explicitly, then:
if it has pointer type, it is initialized to a null pointer;
if it has arithmetic type, it is initialized to (positive or unsigned) zero;
if it is an aggregate, every member is initialized (recursively) according to these rules;
if it is a union, the first named member is initialized (recursively) according to these rules.
Automatic variables that are not initialized have indeterminate value, we can see this by going to the draft C99 standard section 6.7.8 Initialization:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.
using an indeterminate value is undefined behavior. The definition for indeterminate values is as follows:
either an unspecified value or a trap representation
It just may be the case that the values you are ending up with for char are not printable.
There is not default value assigned. Never trust in a default value you didn't assign.

Are global variables always initialized to zero in C? [duplicate]

This question already has answers here:
Why are global and static variables initialized to their default values?
(5 answers)
Closed 6 years ago.
#include <stdio.h>
int a[100];
int main(){
printf("%d",a[5]);
return 0;
}
Does the above code always print '0' or is it compiler specific? I'm using gcc compiler and I got the output as '0'.
Yes, all members of a are guaranteed to be initialised to 0.
From section 3.5.7 of the C89 standard
If an object that has static storage duration is not initialized
explicitly, it is initialized implicitly as if every member that has
arithmetic type were assigned 0 and every member that has pointer type
were assigned a null pointer constant.
"Global variables" are defined at file scope, outside any function. All variables that are defined at file scope and all variables that are declared with the keyword static have something called static storage duration. This means that they will be allocated in a separate part of the memory and exist throughout the whole lifetime of the program.
It also means that they are guaranteed to be initialized to zero on any C compiler.
From the current C standard C11 6.7.9/10:
"... If an object that has static or thread storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;"
Practically, this means that if you initialize your global variable to a given value, it will have that value and it will be allocated in a memory segment usually referred to as .data. If you don't give it a value, it will be allocated in another segment called .bss. Globals will never be allocated on the stack.
Yes.
Any global variable is initialized to the default value of that type.
0 is the default value and is automatically casted to any type.
If it is a pointer, 0 becomes NULL
Global variables get there space in the data segment which is zeroed out.
It is not compiler specific but defined in the C standard.
So it will always print 0.
File scope objects declared without explicit initializers are initialized by 0 by default (and to NULL for pointers).
Non-static objects at block scope declared without explicit initializers are left uninitialized.
Are the globle variable always initalized to zero in C?
Yes and It's defined in the C standard.
It is not compiler specific. The code will always print 0.

Resources