[RESOLVED] Why is ((foo*)NULL)->bar(); undefined?
I've seen code to this effect appear twice on this forum in the last couple of days. Both times the response was that the result is undefined.
Code:
((foo*)NULL)->bar(); // where bar is not static or virtual
I've skimmed through the standard, but found nothing yet.
I'm intending printing off a copy and looking in more depth tonight.
My question:
Is the result undefined because the standard explicitly states that it is, or does the standard simply fail to address the issue?
Thanks very much for you time.
Re: Why is ((foo*)NULL)->bar(); undefined?
Dereferencing a null pointer yeilds undefined behaviour, in my 2005 draft of the standard there is a reference to this in section 1.9 (program execution):
Quote:
4. Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing
the null pointer). [ Note: this International Standard imposes no requirements on the behavior of programs that
contain undefined behavior. —end note ]
Re: Why is ((foo*)NULL)->bar(); undefined?
It's undefined because it is calling a member function on an object that does not exist!
What it is saying is essentially "At address NULL pretend we have an instance of the 'foo' class and call the member function 'bar' in it.
If the function 'bar' accesses no member variables it may work. Or it may not.
Re: Why is ((foo*)NULL)->bar(); undefined?
Because the implicit "this" pointer within foo::bar would be null and any attempt to access a member would imply dereferencing a null pointer, which is undefined behaviour.
Re: Why is ((foo*)NULL)->bar(); undefined?
Thanks PredicateNormative that's getting close to what I'm looking for.
I'm interested in the standard rather than the semantics of the given code. I suppose my reason for asking could be better encapsulated in the following program:
Code:
#include <iostream>
class foo {
int bar() {
if (this == 0) return 0;
else return 1;
}
}
int main(int argC, char ** argV) {
std::cout << ((foo *) 0)->bar();
return 0;
}
It's clear that most compilers will allow this and most of them will simply print 0 and terminate with exit code 0. But the implication in other threads is that the result is undifined.
This supprised me (less so when I took in the intentional simularity between normal and virtual methods) and I'm looking for infomation about it.
Regards
Re: Why is ((foo*)NULL)->bar(); undefined?
While most compilers use a machine language "Jump to Subroutine" instruction for non-virtuals, and a _vptr/_vtable for virtuals, this is by no means mandated by the standard.
Also consider what happens as soon as you overload "operator ->" .....
Re: Why is ((foo*)NULL)->bar(); undefined?
This bit, isn't undefined:
Code:
class foo {
int bar() {
if (this == 0) return 0;
else return 1;
}
}
since in principle it is just comparing a NULL pointer to 0, which is fine. But because that pointer is the this pointer, the process of getting to the code when this is NULL is undefined. i.e.
Code:
int main(int argC, char ** argV) {
std::cout << ((foo *) 0)->bar();
return 0;
}
Constitutes undefined behaviour, because operator-> is dereferencing a NULL pointer, which is undefined behaviour.
The fact that it works on most compilers because of the way they construct machine code for non-virtual member functions, and consequently the way they access them is irrelevant. The fact is, that the behaviour according the the standard is undefined, and therefore code such as the above should never be implemented.
Re: Why is ((foo*)NULL)->bar(); undefined?
TheCPUWizard Thanks, that pretty much explains it.
In different implamentations there may be a completely different meaning to that code.
I've just found this in the 2003 standard which pretty much nails it down.
ISO/IEC 14882 Second edition 2003-10-15
Quote:
9.3.1 Nonstatic member functions
...
If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived
from X, the behavior is undefined.
In this case bar is being called on something which is not an object of type foo.
Thanks for all your responses
Re: Why is ((foo*)NULL)->bar(); undefined?
its undefined because the NT header is not a foo object
Re: Why is ((foo*)NULL)->bar(); undefined?
Sorry I'm not familiour with the term NT header in this context.
And I'm not getting any meaningful hits on google or in the c++ standard.
Re: Why is ((foo*)NULL)->bar(); undefined?
sorry, the correct term is PE Header
the fact on XP dos header direct to nt header.
its only on windows, nott C++ standard
Re: Why is ((foo*)NULL)->bar(); undefined?
Quote:
Originally Posted by
couling
It's clear that most compilers will allow this and most of them will simply print 0 and terminate with exit code 0. But the implication in other threads is that the result is undifined.
It follows from the meaning of undefined behaviour. A compiler can do anything including nothing.