Page 1 of 1

const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 9:53 am
by She
When I compile the following code, the functions implemented by SingletonImplementation seem to be optimized out of the build because they are never being called. Even though my SingletonImplementation::createInstance() is creating a new SingletonImplementation, the functions of its parent class are being invoked when I issue:

Code: Select all

SingletonInterface::getInstance()->iAreNotWorkingLol()
Am I just being retarded here? I can't figure out wtf is going onnnnn. Here's the code:

Code: Select all

// SingletonInterface.h

class SingletonInterface
{
public:
   static SingletonInterface* getInstance() { return instance; }
   virtual bool iAreNotWorkingLol() const { return true; }
protected:
   static SingletonInterface* instance;
};

Code: Select all

// SingletonImplementation.h

class SingletonImplementation : public SingletonInterface
{
public:
   static void createInstance();
   bool iAreNotWorkingLol() const;
};

Code: Select all

// SingletonImplementation.cpp

void SingletonImplementation::createInstance()
{
   if(!instance) instance = (SingletonInterface*)(new SingletonImplementation());
}

bool SingletonImplementation::iAreNotWorkingLol() const
{
   return false;
}

Code: Select all

// main.cpp

SingletonImplementation::createInstance();
Please help! Thanks in advance.

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 11:27 am
by short
She wrote:
Am I just being retarded here?
Yes.

Haha jk, but inside SingletonInterface.h you should be declaring interfaces (function definitions prototype) not bodies.

Within SingletonInterface.h declare

Code: Select all

// derp derp
virtual bool iAreNotWorkingLol() const;
Within SingletonInterface.h

define method again (this time without virtual keyword):

Code: Select all

bool iAreNotWorkingLol() const;
Within SingletonImplementation.cpp

define method body:

Code: Select all

bool SingletonImplementation::IAreNotWorkingLol() const {
  return false;
}

I suggest you remove the body from your SingletonImplementation.cpp and write it in SingletonImplementation.h as the compiler will inline the function for you,
ie:
// SingletonImplementation.h

Code: Select all

bool IAreNotWorkingLol() const { return false; }
The TLDR; you defined your method body in the wrong place, let your SingletonInterface define the method interface, and your SingletonImplementation define your method body (whether it is in SingletonImplementation.h/cpp is up to you)

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 12:13 pm
by She
short wrote:Haha jk, but inside SingletonInterface.h you should be declaring interfaces (function definitions) not bodies.
First of all, "declaring a function interface" and a "function definition" are not the same thing :)

{ return true; } is the definition. I think that's what you meant by "bodies."

Technical jargon stuff, no big deal, but I just wanted to clarify.

Second of all, I wanted my SingletonInterface to include a default behavior, hence the { return true; } definition part in the SingletonInterface.h header file. It's declared virtual so that SingletonImplementation can overload it with its own definition. The problem is, the SingletonImplementation function definition is being optimized out during compilation. And I dunno why, but I don't see how moving my function definition from a .h file to a .cpp file is going to change that.

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 12:40 pm
by short
She wrote:
short wrote:Haha jk, but inside SingletonInterface.h you should be declaring interfaces (function definitions) not bodies.
First of all, "declaring a function interface" and a "function definition" are not the same thing :)
LOL ok, what I meant was function prototype, your right. Updated.
She wrote:Second of all, I wanted my SingletonInterface to include a default behavior, hence the { return true; } definition part in the SingletonInterface.h header file. It's declared virtual so that SingletonImplementation can overload it with its own definition. The problem is, the SingletonImplementation function definition is being optimized out during compilation. And I dunno why, but I don't see how moving my function definition from a .h file to a .cpp file is going to change that.

Code: Select all

void SingletonImplementation::createInstance()
{
   if(!instance) instance = (SingletonInterface*)(new SingletonImplementation());
}
instance is of type SingletonInterface, not SingletonImplementation. It's true type is SingletonImplementation, but it is being stored as SingletonInterface. Your SingletonImplementation function "definition" isn't being optimized out, it's being ignored because instance is being stored as the interface type. When you call a method on it, it's using the type defined by the interface, not the implementation.

You really have two options,

1) move the "instance" member out of SingletonInterface.h and don't define default behavior within the interface, make the members pure virtual (my suggestion). This allows you to move your "instance" member into SingletonImplementation.h as the type it really is, SingletonImplementation.

2) keep everything as is, since you are creating an object of type SingletonImplementation within SingletonInstance (I don't recommend this, you don't want your interface to be dependent on it's implementation type) and cast it to SingletonImplementation before using it:

Code: Select all

// main.cpp

SingletonImplementation::createInstance();
static_cast<SingletonImplementation*>(SingletonInterface::getInstance())->iAreNotWorkingLol()
I honestly thing option 2 is abysmal and should not be done. Does that help point out what is happening?

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 1:56 pm
by She
short wrote:instance is of type SingletonInterface, not SingletonImplementation. It's true type is SingletonImplementation, but it is being stored as SingletonInterface. Your SingletonImplementation function "definition" isn't being optimized out, it's being ignored because instance is being stored as the interface type. When you call a method on it, it's using the type defined by the interface, not the implementation.
Okay but the *type* of the pointer is SingletonInterface, but since I new'ed a SingletonImplementation, instance should be pointing to an instance of SingletonImplementation. So it should know to invoke the child class, SingletonImplementation, functions. This is supported by the fact that when I remove the const-ing from the functions of both SingletonInterface and SingletonImplementation, everything works the way I would expect it to, e.g. SingletonImplementation functions are invoked.

What could it be about const-ing these functions that's screwing me up?

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 2:23 pm
by short
She wrote: Okay but the *type* of the pointer is SingletonInterface, but since I new'ed a SingletonImplementation, instance should be pointing to an instance of SingletonImplementation. So it should know to invoke the child class, SingletonImplementation, functions. This is supported by the fact that when I remove the const-ing from the functions of both SingletonInterface and SingletonImplementation, everything works the way I would expect it to, e.g. SingletonImplementation functions are invoked.

What could it be about const-ing these functions that's screwing me up?
If it's really doing this, then I'm not sure. Perhaps someone else on the forum, or stack overflow :)

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 2:37 pm
by She
short wrote:If it's really doing this, then I'm not sure. Perhaps someone else on the forum, or stack overflow
Yep, it is really doing that. Thanks very much for your responses though :) I really appreciate it. I hope I can find an answer. This is killing me!

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 2:48 pm
by Falco Girgis

Code: Select all

if(!instance) instance = (SingletonInterface*)(new SingletonImplementation());
That downcast would have been done implicitly, so that isn't necessary. Also, I would recommend a static_cast, if you insist on doing it explicitly.
short wrote:instance is of type SingletonInterface, not SingletonImplementation. It's true type is SingletonImplementation, but it is being stored as SingletonInterface. Your SingletonImplementation function "definition" isn't being optimized out, it's being ignored because instance is being stored as the interface type. When you call a method on it, it's using the type defined by the interface, not the implementation.
Wrong. That's the entire point of a virtual function. It should still invoke the child function even though you are referencing it through the parent.

I have a theory as to what is happening...

You code looks polymorphically correct. I would be expecting the same behavior that you are. However, you brought up an interesting point:
she wrote:This is supported by the fact that when I remove the const-ing from the functions of both SingletonInterface and SingletonImplementation, everything works the way I would expect it to, e.g. SingletonImplementation functions are invoked.
You really should have mentioned this in your first post. ;)
she wrote:What could it be about const-ing these functions that's screwing me up?
Nothing, which is what leads me to believe that it's a compiler-error.

Your iAreNotWorking() method is being implicitly declared inline within the parent class. By adding the const, I am almost positive that it is getting immediately inlined without the compiler bothering to look at the virtual table... thus breaking polymorphism.

If you take a moment to think about that function from the optimizer's perspective, it makes sense. Without the "const," it cannot be sure that you aren't modifying members of the child type. So inlining would not be an option. WITH the "const," you are guaranteeing that no member variables are being modified... so it is safe to inline.

In Conclusion
1) Set a breakpoint within SingletonInterface::iAreNotWorking(). You can't, can you? It has been inlined.

2) Move your implementation of SingletonInterface::iAreNotWorking() to your .cpp file. This will prevent the compiler from even having the option of inlining it. Should you have to do this? No. It's a compiler bug. But this is a valid work-around.

OR

2.5) Turn off compiler optimizations for that one file.

3) Come back and tell me how right I was.

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 3:09 pm
by She
omg I hope you're right, Falco. That would be the coolest thing ever. It's pretty amazing that you can guess that.

I'm trying it right now and I'll let you know if it works.

Thanks so much!

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 3:19 pm
by She
Success! That is supremely satisfying. Thaaaaanks!

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 3:22 pm
by Falco Girgis
She wrote:Success! That is supremely satisfying. Thaaaaanks!
No problem at all. You should know by now that the faithful pursuit of The Policy of Pristinity is my job on these boards, Kendall. ;)

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 3:25 pm
by Arce
If you take a moment to think about that function from the optimizer's perspective, it makes sense. Without the "const," it cannot be sure that you aren't modifying members of the child type. So inlining would not be an option. WITH the "const," you are guaranteeing that no member variables are being modified... so it is safe to inline.
You know, this does make perfect sense. And I vaguely recall reading this somewhere. Do you still have my O'Rielly C++ in a Nutsheel pocket reference? Check "const" out in it, I'm pretty sure it describes this exact scenerio.

Re: const functions not compiling in, imp from singleton ifc

Posted: Thu May 03, 2012 3:27 pm
by She
lol, shit.