This question already has answers here:
Accessing class members on a NULL pointer
(8 answers)
Calling class method through NULL class pointer [duplicate]
(10 answers)
Closed 9 years ago.
I created a NULL pointer of class App, but somehow the method of the NULL object(of App) is working. Here is my code:
#include "App.h"
#include <iostream>
using namespace std;
int main()
{
App* pointer = NULL;
pointer->print();
system("pause");
}
Attached the Header file
#pragma once
#include <iostream>
using namespace std;
class App
{
private:
int x;
int y;
public:
App(void);
~App(void);
App(int a, int b)
{
x=a;
y=b;
}
void print()
{
cout<<"hello world"<<endl;
}
};
The running result an the screen in : hello world. Why is that?
Undefined behaviour is just that - undefined. Anything can happen, including the appearance of behaving correctly.
For your case, specifically, you might want to check out the generated assembly from your program. You'll probably find that the compiler has optimized your code and inlined that printout or called it directly rather than actually invoking it through a pointer/table lookup.
Dereferenceing a NULL pointer is undefined behaviour. You should not expect your program not to 'work' just because you do this.
In this case your print function does not 'use' the this pointer so your code executes as you expected. But you should not rely on this, undefined behaviour means exactly what it says.
Invoking a method on a NULL pointer is undefined behavior so anything may happen. You should never count on the fact that the code will always produce this output. Always try to avoid such situations.
It is undefined behavior. The implementation is able to work in this toy example because print does not access member variables and is a non-virtual function.
This is undefined behavior, this thread explains why it most likely works, the basic explanation is that it will probably be transformed into something similar to:
void _App_print( App* this );
and since you are not using this it works.
Because print does not (even implicitly) access any data behind the "this" pointer.
Related
This question already has an answer here:
Why is there an injected class name?
(1 answer)
Closed 9 months ago.
I accidentally noticed that you can pointlessly use :: operator to reefer back to the original struct/class again, for example:
#include <iostream>
struct Test
{
static const int x = 5;
};
int main()
{
std::cout << Test::x; // makes sense
std::cout << Test::Test::x; // still works?
std::cout << Test::Test::Test::x; // okay...
return 0;
}
This can be stacked more and more. However, you can't construct an object this way, because compiler doesn't recognize it as a type, but interprets it as a class::constructor.
Test::Test Obj; // error, not a type
Although if there was a nested class inside, then you could still reference it this way and successfully construct an object.
I was wondering what leads to this, is this a side effect of something else? It seems totally useless but made me curious.
This is injected class name, simmilar question was asked here
This question already has answers here:
Access to protected member through member-pointer: is it a hack?
(4 answers)
Closed 4 years ago.
Consider
class A {
protected:
int m;
};
class B : public A {
void foo(A& a) {
a.m = 42; // ill-formed
}
void bar(A& a) {
auto pm = &B::m;
auto pm2 = static_cast<int A::*>(pm);
a.*pm2 = 42; // is this ok?
}
};
Trying to access A::m directly is ill-formed according to [class.protected]. However, it appears that we can always (?) circumvent this using static_cast, which allows a derived-to-base cast with pointers to members. Or is this somehow UB?
[Coliru link showing that bar compiles]
Yes, you can circumvent the protected mechanism in this way by using static_cast.
I think this is not undefined behavior in this particular case.
By using the static_cast you tell the compiler two things:
You ask the compiler to convert the B pointer into an A pointer.
You tell the compiler that this is ok to do so.
For 1. the compiler applies very limited checks of whether this is okay or not, and for static_cast it allows to cast from derived to base and the other way round, and that is it. So the compiler is happy. Whether a variable or pointer is protected or public is not part of the variable or pointer type. Neither pm nor pm2 carry the protected information.
For 2. the compiler completely leaves it up to you to make the decision whether this is okay or not in your design. It is not undefined behavior. It may still not be a good idea. pm2 is just a pointer to an int in A. You can reset it to a pointer to a different int in A which is public.
The background is that access control in C++ is generally per-class, plus there are some extra rules around protected which try to provide some level of access control on a per instance basis, but this protection is not perfect as you have demonstrated in your interesting question.
This question already has answers here:
About Pointers To Functions in function declarations
(4 answers)
Closed 7 years ago.
In some C++ 98 code (meaning no, using std::function is not an option), I found the following construct:
class someClass
{
public:
typedef void callback();
void setCallback(callback c)
{
mCallback = c;
}
void callCallback()
{
if (mCallback)
mCallback();
}
private:
callback *mCallback;
};
This confused me. I am used to passing callback functions as a function pointer, so I would expect setCallback to take (*callback)() as argument.
However, the above code seems to work, and compiles without any (related) warnings.
Could someone tell me what is happening here? Is my callback function implicitly passed as a function pointer? Is it a good idea to use this instead of function pointers?
The only thing I could find is that this construction results in "parameter-declaration-clause" ambiguity (C++ 98 8.3p7). Is this the only downside? Are there any benefits?
Similarly to arrays, parameters of function type declare, in fact, a pointer to that type.
This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 8 years ago.
I would expect the following code to crash at runtime with a null pointer error:
#include <memory>
#include <iostream>
#include <cassert>
struct Foo {
void echo() {std::cout << "Echo" << std::endl;}
};
int main()
{
std::unique_ptr<Foo> up(new Foo());
up.reset(nullptr);
assert(up.get() == nullptr);
up.get()->echo();
}
however both gcc (4.7/4.8/4.9), msvc (2013 and upcoming 2015) and clang (3.5) happily outputs:
Echo
and assert is not firing so up.get() is nullptr.
You are essentially calling a member function with an invalid object argument - which is generally considered to trigger undefined behavior. However, you are not using this inside the member funtion, so no Segfaults should occur practically.
Try adding a member and accessing that member inside echo. That should crash your program. I.e.
struct Foo
{
int i;
void echo() {std::cout << i << std::endl;}
};
Calling member function through NULL pointer is surely an undefined behavior.
Your call to that member function is successful as you are not making use of this pointer.
This question already has answers here:
Accessing class members on a NULL pointer
(8 answers)
Closed 9 years ago.
Why is it possible to use class member functions on an uninitialized object (at least I believe it's uninitialized). The following runs without error:
// A.h
class A {
public:
explicit A(int n) : n_(n) {};
~A() {};
int foo() {
return n_;
};
int bar(int i) {
return i;
};
private:
int n_;
};
with
// main.cc
#include <iostream>
#include "A.h"
int main(int argc, char **argv) {
A *myClass;
std::cout << myClass->bar(5) << "\n";
}
Now, certainly attempting myClass->foo();fails, but why can we even use bar() when all we've declared is that a pointer to A exists, and is called myClass? Is this acceptable coding style/is there ever a reason to use this approach?
why can we even use bar() when all we've declared is that a pointer to A exists, and is called myClass?
Because, in general, it's impossible for the compiler to tell whether a pointer will be valid at runtime; so it isn't required to diagnose this error. However, in this case, a decent compiler should be able to issue a warning, as long as you're not building with warnings disabled.
Is this acceptable coding style/is there ever a reason to use this approach?
Absolutely not. Dereferencing an invalid pointer gives undefined behaviour.
Because you can't know if the block of memory where myClass is pointing to is an initialized object, it have right syntax, but undefined behavior, however if want to prevent, you should use -Wall or a similar compiler option (depends on your compiler) and it will warn you about the uninitialized pointer.