1

I have tried this:

class A{
    void fun()
    {
        cout<<"Hello World";
    }
};

int main()
{
    A* obj;
    obj->fun();
}

It prints "Hello World". but I havent allocated any memory.

robbannn
  • 5,001
  • 1
  • 32
  • 47
Prateek
  • 51
  • 6
  • 2
    This is [undefined behaviour](http://blog.regehr.org/archives/213). – TartanLlama Sep 09 '14 at 09:36
  • It is *undefined behaviour* to de-reference an invalid pointer. – juanchopanza Sep 09 '14 at 09:36
  • Not exact duplicate, but closely related: http://stackoverflow.com/questions/17238284/c-call-a-non-virtual-non-static-method-from-a-null-pointer-without-accessing/17238326#17238326 – Suma Sep 09 '14 at 09:39
  • You called it, and it worked - so yes, we can call a member function this way. But if you tried usin `*this` object, the program would probably crash. So if you want to call a function this way, the function must not use `this`, and then you can declare the function as `static void fun()`. Such function can be invoked directly with a class prefix as `A::fun()`, without any 'nonexisting object' for the `->` operator. – CiaPan Sep 09 '14 at 09:41
  • @juanchopanza Note OP actually did not dereference an invalid pointer. – CiaPan Sep 09 '14 at 09:42
  • @CiaPan OK, accessing a member via `->` from an invalid pointer is UB. – juanchopanza Sep 09 '14 at 09:45
  • @CiaPan `->` references the pointer. It may not actually access memory pointed by pointer, but even then it is still Undefined Behavior. For example, optimizer might do funny things. Or the class might have virtual methods, in which case it would crash when it tries to access the vtable. Really, you can not trust it to work in any modern compiler, even if common sense says "it should work". If you inspect some actual machine code of some actual binary, then you can trust that binary to work, but if you recompile it with different options or different compiler, all bets are off again. – hyde Sep 09 '14 at 09:47
  • Right, **if** the function is virtual or **if** the function is inherited from virtual base class, then the code would try to access vtable for a function address or a `this` displacement and probably crash. This is (part of) what I meant by dereferencing a pointer. But in the example given none of those conditions occurs and OP's experiment works. So the short answer for the question 'can we call (...) without allocating memory?' is of course 'yes, we can', although the more general question 'can we call different types of functions this way?' will certainly get answer 'NO.' – CiaPan Sep 09 '14 at 10:50

4 Answers4

8

The code in question has undefined behavior, using an indeterminate value for the pointer.

It might crash, or do anything, including that it might work.

If a member function doesn't need an instance, make it a static member function; then you can call it like A::fun().

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 1
    To add to your answer, if `obj` gets assigned `0`, the problem of using an indeterminate value may be resolved, but the call `obj->fun()` would still be invalid. To call a non-static member function of a class, you *need* an instance of that class. –  Sep 09 '14 at 09:39
0

It is an undefined behavior since the pointer has an undefined value. Even if you try to assign the value 0 to obj then also the obj->fun() will be undefined and will result in undefined behavior.

The C++ standard says:

If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
0

You can do it this way --

#include <stdio.h>

class A{

public:
static void fun()
{
    printf("Hello World\n");
}
};

int main()
{
    A::fun();
}

Advantage:

  1. No need to create object.
  2. By adding header of this class you can call this function from anywhere.
Robel Sharma
  • 964
  • 1
  • 11
  • 26
0

§9.3.1 [class.mfct.non-static]/p2:

If a non-static 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.

T.C.
  • 133,968
  • 17
  • 288
  • 421