Can someone please explain me difference between Null pointer and uninitialized Pointer
Can someone please explain me difference between Null pointer and uninitialized Pointer
You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.
And a pointer will never point to NULL unless you have assigned NULL to that pointer.
Jim
You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.
What you say is true, but it's beside the point. An uninitialised pointer also MIGHT NOT be NULL. Relying on it being NULL is foolhardy. Some compilers do that. Some do not. I know of one compiler which set uninitialised variables to zero but, after a compiler update, did not.
Accessing the value of any uninitialised variable yields undefined behaviour - and the standard does not stipulate any constraints on what should or should not happen as a result.
Comparing an uninitialised pointer with NULL may yield a true result, it may yield a false result, it may erase your compiler without trace from your system, or an infinite number of other possibilities. That is because, in order to compare a pointer with something, it is necessary to access the value of that pointer - and the simple act of accessing the value has undefined behaviour.
Even worse, with pointers, the reason to access the value of the pointer is usually to dereference it - access what it points at. Accessing the value of the pointer itself yields undefined behaviour. If that operation even yields a pointer value, dereferencing that pointer value could do anything.
Is accessing an uninitialized memory actually undefined? I don't think it is. The value can be anything, with no guarantees that it's even equal to itself. But undefined behavior would mean not only that you can't rely on the result, but that reading the value itself is not allowed. For example, you might memcopy a union with fields of different sizes, thereby copying uninitialized data when a small field or no field has been set in the union. That's surely allowed.
It is too clear and so it is hard to see.
A dunce once searched for fire with a lighted lantern.
Had he known what fire was,
He could have cooked his rice much sooner.
O_oThat is because, in order to compare a pointer with something, it is necessary to access the value of that pointer - and the simple act of accessing the value has undefined behaviour.
That is wrong.
[Edit]
I original said "inspecting" here, but that implies comparison so I've changed the line.
[/Edit]
The value is undefined, but accessing the value has well-defined semantics.
The code has defined semantics.Code:void * s; if(s) { s = 0; }
[Edit]
You may be thinking more along the lines of `double' variables or other types with traps/values representing an undefined state.
I could understand the assertion in that context, but the access itself is still well-defined.
The result of comparing `a.m' and `b.m' is undefined, yet the code has well-defined semantics.Code:typedef struct Whatever_{float m;} Whatever; // ... Whatever a,b; a = b;
[/Edit]
Soma
Last edited by phantomotap; 03-02-2014 at 12:25 PM.
“Salem Was Wrong!” -- Pedant Necromancer
“Four isn't random!” -- Gibbering Mouther
Not according to the standard, it doesn't. The if (s) call access the value of s, in order to compare it with zero, and that accessing has undefined behaviour.
The description is in Section 4.1 of the C++98 standard (I don't have a copy of a more recent standard handy, but doubt the rules have changed in this case, because it is one of those things inherited from C) which talks about "lvalue-to-rvalue conversion", which is standardese for accessing the value of an object (and is the operation that permits an object to be on the right hand side of an assignment operator, hence the name). The first para of that section stipulates that the lvalue-to-rvalue conversion on an uninitialised object has undefined behaviour.
No I'm not. The rules surrounding lvalue to rvalue conversion apply to all types. It is not specified as applicable to some types but not others.
Yes, particular implementations do what you describe. It means that the implementer made a decision to do it the way you describe, despite the standard leaving it undefined. The fact that doing it that way seems logical to you (and to me) does not mean the standard requires it. But it is the standard that is the basis for something being undefined, not an implementation.
A compiler may wish to optimize based on when a variable becomes live, which is when it is first given a value. For example, if a variable is only assigned to near the end of a function, but declared at the top it could share memory with another variable. This could break code that reads the uninitialized variable but and relies on it not changing.
It is too clear and so it is hard to see.
A dunce once searched for fire with a lighted lantern.
Had he known what fire was,
He could have cooked his rice much sooner.
O_oThe first para of that section stipulates that the lvalue-to-rvalue conversion on an uninitialised object has undefined behaviour.
I read the standard differently than you. I see it saying the resulting "lvalue" is undefined, but that the access itself as being defined.
Your interpretation mandates undefined behavior for such conversions which evaluate component types, and I don't think that is the case, but I will say that your interpretation may be correct.
You misunderstand; I was saying you may have just combined aspects of one standard--such as a given processor manual--with the C++ standard; I did not say that the C++ standard covers rules like was offered in the example.It means that the implementer made a decision to do it the way you describe, despite the standard leaving it undefined.
Soma
“Salem Was Wrong!” -- Pedant Necromancer
“Four isn't random!” -- Gibbering Mouther
If I misunderstood your assertion of what I may have been thinking, there's a fair chance your assertion was incorrect.
O_oIf I misunderstood your assertion of what I may have been thinking, there's a fair chance your assertion was incorrect.
What?
Simple misunderstandings happen all the time. I corrected the misunderstanding because you needlessly defended a position no one attacked. The C++ standard--and inherited C standard--is solely relevant regardless of which interpretation here discussed is correct, yet the fact remains, you confuse different standards, misinterpret the standard, and employ the wrong standard on occasion the same as I. I thought, still assert in fact, this thread may be one such case, and you misunderstanding/misrepresenting the fact doesn't make the assertion wrong.
*shrug*
How would you misunderstanding something I said alter, in any way, whether or not what I said was correct? That is laughable and absurd.
Soma
“Salem Was Wrong!” -- Pedant Necromancer
“Four isn't random!” -- Gibbering Mouther
This code is well defined:
Memcopy implies using the uninitialized buffA. This code needs to be well defined in order of it to be well defined to copy class types with uninitialized members.Code:#include <cstring> int main(){ char buffA[10]; char buffB[10]; memcopy(buffB,buffA,10); return 0; }
However, this code is not:
The reason is, the value of s not guaranteed to stay the same until it is assigned to. So during the if statement it might be 0, but after foo, it might be non-null. This doesn't happen in practice, but the value of s result of a read from uninitialized memory is undefined/unspecified, which has this implication.Code:void foo(){ } int main(){ void * s; if(s) { s = nullptr; } foo(); delete s;//would be ok if s is nullptr, otherwise an error. return 0; }
It is too clear and so it is hard to see.
A dunce once searched for fire with a lighted lantern.
Had he known what fire was,
He could have cooked his rice much sooner.
O_oThis code needs to be well defined in order of it to be well defined to copy class types with uninitialized members.
The values of the uninitialized members and values of the copy of those members are undefined, but the access itself--within `memcpy'--is well-defined?
We agree if that is your assessment, but we disagree on why that must necessarily be the case.
The code is undefined because you are using the undefined value--which remains undefined because the `if' branch may or may not have executed--on line 11.This doesn't happen in practice, but the value of s result of a read from uninitialized memory is undefined/unspecified, which has this implication.
Let us return to your example which you say is well-defined:
You said "A compiler may wish to optimize based on when a variable becomes live, which is when it is first given a value."; if that is the case, the above code also exhibits undefined behavior because `memcpy' does not assign a value to `buffA' or the elements of `buffA'.Code:#include <cstring> int main(){ char buffA[10]; char buffB[10]; memcopy(buffB,buffA,10); return 0; }
You said "This doesn't happen in practice, but the value of s result of a read from uninitialized memory is undefined/unspecified, which has this implication."; if that is the case, the above code also exhibits undefined behavior because the values assigned within `memcpy' are necessarily the "result of a read from uninitialized memory".
I am unsure of your actual opinion because you can't really have it both ways.
So, with that in mind, let us make a small change:
I assert that the code is well-defined because `buffA' must necessarily exist and the mechanics of access and assignment must not be undefined simple because the value provided for copy is undefined. The values are obviously undefined, and the values obviously remain undefined, but that changes in no way my assertion.Code:#include <cstring> int main(){ void * buffA[10]; void * buffB[10]; memcpy(buffB,buffA,10*sizeof(void*)); //if(buffA[0])delete buffA[0]; return 0; }
If you remove the comment, rather compile the line, the result is undefined behavior because you are doing "something more"/"something other" than just "accessing" the value.
Soma
Last edited by phantomotap; 03-03-2014 at 05:36 PM.
“Salem Was Wrong!” -- Pedant Necromancer
“Four isn't random!” -- Gibbering Mouther