Behavior of uninitialized local char? - c++

If you have lets say a local int that is uninitialized, then its gets an undefined value but if you have a local char variable should that not have an undefined value as well? Of course 0 could be that undefined value, but i was wondering if char is any different, since all related info i find is about int and the program below just outputs 0 when the char variable is cast to an int. Im using GCC 4.7 with no flags.
int main()
{
char test1;
int test2;
std::cout<<test2; //garbage
std::cout<<std::endl;
std::cout<<(int)test1; //0
return 0;
}

Uninitialised means really uninitialised. Just because you consistently get a particular value on your machine at a particular time, doesn't mean that will always be the case all the time on all machines.
You can verify that nothing is initialising your variable by dumping the assembly code for your function and inspecting it.

If you have lets say a local int that is uninitialized, then its gets an undefined value
No, that isn't the right way to think about it. Your local variable doesn't get an undefined value, it gets no value whatsoever. Subsequently querying such an uninitialized variable invokes undefined behavior.
Your program won't necessarily print "0". It won't necessarily print any number, or even anything at all. Granted, on typical computers, using typical compilers, your program will print some number, but within the scope of the C++ language, we can't make any prediction about what your program will do or not do.

Local variables get their initial values from whatever random data is in the stack space they occupy at that moment. There is no guarantee that space contains zeros.

Related

Using garbage value(not initialized value) as id

Before ask I'm not the native speaker pardon for my poor english
Reading some book about c++ and the book mentioned variables should be initialize after declared. Otherwise variable having a garbage value and this may cause some problem. This garbage values are random and not predictable, what if using this garbage value as a ID?
I tried to find relational topic an google and couldn't find any result
Please leave a comment of idea of references
When you initialize a non-static(local) variable and use/read/print it before assigning a variable to it, the action is undefined behavior.
When you encounter undefined behavior:
You cannot assume that there's any value in that memory space to begin with
You cannot assume that the value won't change throughout the code execution, therefore, it's not ideal to use it as an ID
You cannot even assume that the program will run, or it will crash/freeze/etc... as everything action from that point on is undefined
Theoretically, an undefined behavior permits anything to happen (obviously in reality there's many restrictions to try and keep it from doing everything and probably sending everyone your pictures, corrupt all your files and frying your computer afterward).
For example, with this piece of code:
int num;
int a = num;
int b = num;
When you print it out, a and b is not guaranteed to have identical value, or the program will run at all. It's different with each systems/compilers.
As such, one must never rely on an undefined behavior to act normally.
Quote from #AnT:
So in general, the popular answer that "it is initialized with
whatever garbage was in memory" is not even remotely correct.
Uninitialized variable's behavior is different from that of a variable
initialized with garbage.
However, never mistakes undefined for inconsistency/randomness. For a (pretty bad) real life example, a broken pipe may be unexpected behavior, but the stream of water that hits you isn't inconsistent or random (until the pipe is fixed, of course).
An example when undefined behavior isn't simply taking some garbage value and results in some bizarre stuff: https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633
Related :
Uninitialized variable behaviour in C++
What happens to a declared, uninitialized variable in C? Does it have a value?
Nothing guarantees that an uninitialized variable contains garbage. It may be garbage, but in fact, any access to such variable yields undefined behavior, which means that literally anything may happen. It may be garbage, it may be constant, it may crash, it may contain previously used data, it may work like expected, but only with some compilers, etc. One is not supposed to rely on anything that comes from such variable and build any logic based on that. And, certainly, it cannot be a source of uniqueness or randomness.
First of all you should not use garbage value as ID.
Since not detail about your question, I am Considering your id is an unique value also by using your ID you are going to retrieve some value.
if that is the case then,
you cannot because on each and every run your garbage value may change.
And Garbage value in the sense it may be a numerical alphanumerical even not a proper value may come.

why wild pointer holds zero address rather than garabge address?

I have been trying to find the size of an particular datatype like "int" without using sizeof() and found this :
#include<stdio.h>
int main() {
int *ptr; /*Declare a pointer*/
printf("Size of ptr = %d\n",ptr);
ptr++;
printf("Size of ptr = %d\n",ptr);
return 0;
}
This returns correct size for int. How?
Isn't wild pointer suppose to contain garbage address rather than zero. And if it contains zero how is it different than NULL pointer as NULL is (void*)0 ?
Since ptr is uninitialised, its value is indeterminate and accessing its value gives undefined behaviour. The meaning of "undefined", somewhat ironically, is defined by C and C++ standards to mean something like "this standard doesn't constrain what happens".
Beginners often incorrectly assume this means it must contain a "garbage value" or be a "wild pointer" or "add some colourful description here" but that is simply not the case.
The meaning of "value is indeterminate" or "the behaviour on accessing the value is undefined" is that any behaviour is permitted from code that accesses the value.
Accessing the value is necessary to print it, increment it, or (in case of a pointer) dereference it (access contents of the address identified by the pointer's value).
The behaviour of code that accesses the value is undefined. Giving a printed value of zero, 42, or a "garbage value" are all correct outcomes. Equally, however, the result could mean no output, or undesirable actions, such as reformatting a hard drive. The behaviour may even change over time if the code is executed repeatedly. Or it may be 100% repeatable (for a specific compiler, specific operating system, specific hardware, etc).
Practically, it is quite common for code with undefined behaviour to give no sign of malfunction during program testing, but to later cause some nasty and visible but unintended effect when the program is installed and executed on a customer's computer. That tends to result in grumpy customers, bug reports that the developers may be unable to replicate, and stress for developers in trying to fix the flaw.
Trying to explain why undefined behaviour results in some particular outcome (such as printing a value of zero) is therefore pointless.
the first print will have garbage or zero, depends on your compiler and previous value that was in the memory location.
If it was zero, then the second print will have the size of int, because incrementing a pointer increments with the size of the pointee.
for instance:
char *x = 0;
x++; //x=1
int *y = 0;
y++; //y=4
In your case, if you got a 0 on the first print, it was the same as if you initialized it to NULL, but you can't count it to always be zero.

is null value is equal to zero(0)? [duplicate]

This question already has answers here:
C++: Uninitialized variables garbage
(5 answers)
Closed 4 years ago.
A programmer told me that if we don't assign a value to any variable e.g like max then it consider as null value.
{
int max=0,x[5];
for(int a=0;a<5;a++)
{
cout<<"Enter no "<<a+1<<" : ";
cin>>x[a];
if(max<x[a])
{
max=x[a];
}
}
cout<<endl<<max;
}
output:
Enter no 1 : 1
Enter no 2 : 5
Enter no 3 : 8
Enter no 4 : 7
Enter no 5 : 5
8
and when type max=0 means at the declaration assign 0 to max
it gives me the same result that's mean null value is equal to 0.
if yes then what is difference between null value and 0
It actually depends on what programming language are you writing your code in.
For instance, if you access in read an uninitialized variable in c/c++ you cannot know which value it will give you.
Memory is not zero-ed when the variable is allocated, so whatever bits were there, they will be read as a value in the type of that variable.
Game Maker's own language, GML, allows you to decide at compile time if uninitialized variables have to be set to 0 by default or not; but any decent programmer would set that option off and not rely on it; i'm not aware of other languages that automatically initialize variable values.
I'd say relying on such a feature is bad practice.
About the difference between null and 0, it actually depends on the base type of your variable.
An integer can only store integers, so null will still be readable as an integer.
If you default initialize a fundamental-type object (such as int) in automatic storage, the value will be indeterminate. The behaviour of reading an indeterminate value is undefined.
Undefined behaviour means that the standard doensn't constrain the behaviour of the program in any way. As far as the C++ standard is concerned, possible behaviours include, none which are guaranteed:
Output that you expect.
Output that you don't expect.
Same output as some program which doesn't have UB.
Different output than some program which doesn't have UB.
Any output.
No output whatsoever.
Side-effects that you expect.
Side-effects that you don't expect.
Any Side-effects.
No Side-effects whatsoever.
Possible side-effects include:
Corruption of data.
Security vulnerabilities.
Anything within the capability of the process, hopefully limited by the OS.
Inconsistent behaviour on other systems.
Inconsistent behaviour even on same system if you re-compile using another compiler.
Inconsistent behaviour even if you re-compile using same compiler.
Inconsistent behaviour even without recompilation during another execution:
Possibly only when you're on vacation.
Possibly only when you're demonstrating your program to your employer or important client.
Consistent behaviour in all of the above cases.
A programmer told me that if we don't assign a value to any variable e.g like max then it consider as null value.
There is no such thing as null value integer in C++. There is such thing as a null pointer, as well as null character, neither of which are directly related to each other, and neither have anything to do with an uninitialized variable.
Your programmer is using confusing terminology, but if by null value, they meant indeterminate value, then they are correct. And in that case your question becomes what is difference between indeterminate value and 0, and the answer is that reading an indeterminate value is undefined behaviour (see above).
when type max=0 means at the declaration assign 0 to max
To be pedantic, you have int max=0 which is not an assignment, but initialization.
There's no 'null' value in c++. Local primitives are uninitialized (you'll get garbage that just happens to be in memory at this time), while static and global variables are zero-initialized. So by saying int max; You'll either get random garbage or zero (depending on where you declared it).

Why does an unassigned int have a value?

If i run the following code it shows a long number.
int i;
int *p;
p= &i;
cout<<*p;
Why does an unassigned int have a value? And what is that value?
The value of the pointer p is the address of the int i. You assigned it with the address-of & operator: p = &i. The int i itself is not initialized also called default initialized. When you dereference your pointer with *p you get the value of your uninitialized int i which could be anything.
The value of your int i is the uninitialized memory interpreted as int. Using uninitialized variables is undefined behaviour.
Also you would have the same behaviour without a pointer by simply doing:
int i;
cout << i;
Because this is what "undefined behavior" means in C++.
"Undefined behavior" means "anything is possible". This includes:
You getting some random value for the object. It can be always the same, or different every time you run the code.
The program crashes.
Your computer starts playing the latest Justin Bieber video, all by itself, with no way to stop it.
The universe, as you know it, comes to an end.
etc... That's what "undefined behavior" means.
Imagine you want to buy a land, where you intend to build a house. To buy a land, you contact the local land seller.
You need to tell him how much units of land you need. In return, he will tell you the location of the land.
Done - your land is ready for use. But did you notice something ? The land seller only told you the coordinates of the land. He didn't say anything about the land. On the land there could be already existing house. There could even be a Hotel, or an Airport. Who knows what is there? If you try to use land, without building your house first, you have no guarantee what will be there. It is your responsibility as a land owner, to build something on top of the land, and use it as appropriate.
C/C++ is the same as the above example. Asking for a int, is like asking for a land with size of 8 units. C/C++ will give you the land, telling you its coordinates. It won't tell you what the land contains. You're responsible for using the land to put a house on top of it. If you don't put a house, and try to enter "the house", you might end up in a Airport. Hope it's clearer now :).
Simply because the memory location where i is has some value (whatever value it is). As Sam pointed out, it is a good example of undefined (and unwanted) behavior.
Because variables can't be empty.
Every byte of computer memory always contains something.
Computer programs usually don't clean up memory when they done with it (for speed reasons), thus when you leave a variable uninitialized, it will have some random (more or less) value which was left in this place of memory by another program or by our own code.
Usually it is 0 or a value of some other variable that was recently destructed or some internal pointer.
The current contents of the memory location ( in the stack ) of the variable i.

How internally this works int const iVal = 5; (int&)iVal = 10;

I wanted to know how the following works # compiler level.
int const iVal = 5;
(int&)iVal = 10;
A bit of m/c or compiler level answer would be great full.
Thanks in advance.
It is undefined behavior.
In the first line you define a constant integer. Henceforth, in your program, the compiler is permitted to just substitute iVal with the value 5. It may load it from memory instead, but probably won't, because that would bring no benefit.
The second line writes to the memory location that your compiler tells you contains the number 5. However, this is not guaranteed to have any effect, as you've already told the compiler that the value won't change.
For example, the following will define an array of 5 elements, and print an undefined value (or it can do anything it wants! it's undefined)
int const iVal = 5;
(int&)iVal = 10;
char arr[iVal];
cout << iVal;
The generated assembly might look something like:
sub ESP, 9 ; allocate mem for arr and iVal. hardcoded 5+sizeof(int) bytes
; (iVal isn't _required_ to have space allocated to it)
mov $iVal, 10 ; the compiler might do this, assuming that you know what
; you're doing. But then again, it might not.
push $cout
push 5
call $operator_ltlt__ostream_int
add ESP, 9
C-style cast acts as a const_cast. Like if you've written
const_cast<int&>( iVal ) = 10;
If you happen to do so and the compiler decides not to allocate actual memory for iVal, you run into undefined behaviour.
For example, VC7 compiles it allright. It even runs it allright in Debug mode. In Release mode iVal value doesn't change after the assignment – it remains 5.
So you should not do so ever.
Why not run it through your cown ompiler and look at the assember output?
This is possible because the idea of "const-ness" only exists in the language/compiler. In actual computer memory, everything is variable. Once the code has been compiled, your iVal variable is simply a location in RAM.
edit: the above assumes that the constant is actually placed in memory. See sharptooth's answer.
Using the c-style cast tells the compiler to treat this memory location as if it were a simple integer variable, and set that value to 10.
Undefined behavior.
In release builds, most compilers will substitute the const value directly - but you could run into one that does a memory load. Also, the second assignment might or might not generate an access violation, depending on platform and compiler. Iirc Intel's compiler puts const data in read-only memory, and would thus generate an access violation at runtime.
If this were an embedded system, it's likely that iVal would be stored in flash, so writing to it would have no effect.
However, it is possible that the compiler would not regard this an error, as embedded compilers generally don't keep track of whether a particular area of memory is readable or not.
I suspect that it might pass the linker too, as a linker will typically determine that iVal is a constant, so goes in flash - but it's not the linker's job to determine how iVal is used.
Incidentally, this question is tagged with "C", but the "(int&)" syntax is not (AFAIK) valid C. The same could, however, be achived with something like:
int *Ptr = (int *) &iVal;
*Ptr = 10;