Why does calling method through null pointer work in C++?
The pointer isn't needed to call the method. The type of the pointer is known, so the code for the method is known. The method doesn't use this
, so it runs the code just fine. It's undefined behavior, but its more efficient not to check if the pointer is NULL, so it runs.
Why is it okay to call free with null pointer?
The malloc
function (as well as calloc
and realloc
) may return a NULL pointer if the requested size is 0. Therefore, it makes sense that NULL pointer can also be passed to free
since it was returned from a successful call to malloc
:
Section 7.22.3p1 of the C standard specifies this behavior:
If the space cannot be allocated, a null pointer is returned. If the
size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except
that the returned pointer shall not be used to access an object.
Does calling a method on a NULL pointer which doesn't access any data ever fail?
Can you think of any plausible reason why any future compiler wouldn't behave as expected?
A helpful compiler might add code to access the real object under the hood in debug builds in the hope of helping you catch this issue in your code early in the development cycle.
What if the function does modify members, but the NULL ptr is guarded against. For instance,
void foo::blah()
{
foo* pThis = this ? this : new foo();
pThis->i++;
}
Since it is undefined behavior to call that function with a null pointer, the compiler can assume that the test will always pass and optimize that function to:
void foo::blah()
{
this->i++;
}
Note that this is correct, since if this
is not null, it behaves as-if the original code was executed, and if this
was null, it would be undefined behavior and the compiler does not need to provide any particular behavior at all.
Why calling function with nullPtr does not crash my application?
This is a common thing in C++, the function is not part of the instance, but part of the class definition.
If you tried to access this
in the function then you would have a crash.
As @YSC mentioned below, this is considered undefined behavior, and you should not assume this will work. but it will mostly work and i heard this is even asked in C++ interviews questions.
Pointer this of a class turns into null when calling a method of that class C++
The assumption: "textures is not null pointer because i can access to "applyTexture" from there." is wrong. applyTexture
is not a function pointer, it's a class method.
The compiler actually converts your object notation call into:
PAGTexture::applyTexture(textures, t + i, id_revol.at(i));
passing nullptr
doesn't bother the compiler like at all. But when entering the method, this==nullptr
and it crashes when you access a member.
It's different with data members (would probably have crashed at once), hence your confusion.
To play it safe, you could do things like:
void PAGTexture::loadTexture(char * path_img, GLuint min_filter, GLuint mag_filter)
{
assert(this!=nullptr);
that will crash with a failed assertion if method is called with a null pointer (note: only works if optimizations are turned off, else the compiler assumes that this
cannot be nullptr
when optimizing even with -O1
)
Why would code explicitly call a static method via a null pointer?
Static member functions were added into C++ in 1989, in Release 2.0 of the AT&T C++ Language System (pre-standardisation). Prior to that, the static
keyword could not be used to declare static member functions, so code authors used workarounds, principally the one you have observed of indirecting a null pointer.
In the Selected Readings accompanying version 2.0 of the AT&T C++ Language System, in section 1-22, Stroustrup writes:
It was also observed that nonportable code, such as:
((X*)0)->f();
was used to simulate static member functions. This trick is a time bomb because sooner or later someone will make an
f()
that is used this wayvirtual
and the call will fail horribly because there is noX
object at address zero. Even wheref()
is not virtual such calls will fail under some implementations of dynamic linking.
Your code was written to compile under Cfront 1.0 or by someone who was not aware at the time of the addition of static member functions to the language.
The annotation of the member function with static
is indeed a puzzle, as Cheers and hth. - Alf has observed; Cfront 1.0 would have rejected that code with:
error: member Method() cannot be static
so it cannot have been there initially. I think Potatoswatter is most likely correct; static
was added at a later date to document and enforce the static method attribute of Method
, once a C++ 2.0 compiler could be guaranteed to be available, but without the calling code being updated. To confirm this you'd need to interview the original programmer(s) or at least examine source control history (if any exists).
Calling class method through NULL class pointer
Under the hood most compilers will transform your class to something like this:
struct _ABC_data{
int a ;
};
// table of member functions
void _ABC_print( _ABC_data* this );
where _ABC_data
is a C-style struct
and your call ptr->print();
will be transformed to:
_ABC_print(nullptr)
which is alright while execution since you do not use this
arg.
UPDATE: (Thanks to Windows programmer for right comment)
Such code is alright only for CPU which executes it.
There is absolutely positively no sane reason to exploit this implementation feature. Because:
- Standard states it yields undefined behavior
- If you actually need ability to call member function without instance, using
static
keyword gives you that with all the portability and compile-time checks
What will happen when I call a member function on a NULL object pointer?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun"
since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
Related Topics
How to Iterate Over a Priority_Queue
Can Someone Please Explain the "Indices Trick"
Why Does the Most Negative Int Value Cause an Error About Ambiguous Function Overloads
How to Return in Void Function
How to Add and Subtract 128 Bit Integers in C or C++ If My Compiler Does Not Support Them
Faq: Why Does Dynamic_Cast Only Work If a Class Has at Least 1 Virtual Method
What Does a Backslash in C++ Mean
Cancelling Boost Asio Deadline Timer Safely
I Want to Convert Std::String into a Const Wchar_T *
Most Efficient/Elegant Way to Clip a Number
Simple Glob in C++ on Unix System
Override a Member Function with Different Return Type
Programmatically Reading a Web Page