C++ compilation problem

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
Rex_VF5
Posts: 44
Joined: Wed Dec 26, 2007 6:24 am

C++ compilation problem

Post by Rex_VF5 »

First of all I swear I have gone through searching for solution and I have tried reordering libs and also adding extern "C" on every possible place. Nothing helped (maybe because I am pretty lame with C/C++ and much more skilled with Java). I am running SDK built out of SVN. I have narrowed the problem to be in static method of a class. Please help. Here's the scenario:

make output

Code: Select all

psp-gcc -I. -I/opt/toolchains/psp//psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150  -L. -L/opt/toolchains/psp//psp/sdk/lib   test.o -lstdc++ -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o test.elf
test.o: In function `main':
test.cpp:(.text+0x30): undefined reference to `XXX::Instance()'
collect2: ld returned 1 exit status
make: *** [test.elf] Error 1

Makefile

Code: Select all

PSPSDK = $(shell psp-config --pspsdk-path)
PSPLIBSDIR = $(PSPSDK)/..
TARGET = test
OBJS = test.o
LIBS = -lstdc++

CFLAGS = -O2 -G0 -Wall
ASFLAGS = $(CFLAGS)

include $(PSPSDK)/lib/build.mak
test.h

Code: Select all

#ifndef TEST_H
#define  TEST_H

#include "XXX.h"

class Test {
        public:
                Test();
                ~Test();
};

#endif // TEST_H
test.cpp

Code: Select all

#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <pspmoduleinfo.h>

/* Define the module info section */
PSP_MODULE_INFO&#40;"test", 0, 1, 0&#41;;

int main&#40;int argc, char* argv&#91;&#93;&#41;&#123;
        Test* test = new Test&#40;&#41;;
        XXX* xxx = XXX&#58;&#58;Instance&#40;&#41;;
        return 0;
&#125;


Test&#58;&#58;Test&#40;&#41;&#123;
&#125;

Test&#58;&#58;~Test&#40;&#41;&#123;
&#125;
XXX.h

Code: Select all

#ifndef xxx_
#define xxx_

/* Export these Classes */
#pragma GCC visibility push&#40;default&#41;

#include <stdio.h>
using namespace std;

class XXX&#123;
        public&#58;
                /**
                 * Get an instance of the XXX class &#40;Singleton Implementation&#41;
                 */
                static XXX* Instance&#40;&#41;;
 &#125;;

#pragma GCC visibility pop

#endif //xxx_
XXX.cpp

Code: Select all

#include <iostream>
#include "XXX.h"

//#include "XXXImpl.h"

XXX* instance = NULL;

XXX* XXX&#58;&#58;Instance&#40;&#41;&#123;
        if &#40;instance == NULL&#41; instance = new XXX&#40;&#41;;
        return instance;
&#125;
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Re: C++ compilation problem

Post by hlide »

Rex_VF5 wrote: make output

Code: Select all

psp-gcc -I. -I/opt/toolchains/psp//psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150  -L. -L/opt/toolchains/psp//psp/sdk/lib   test.o -lstdc++ -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o test.elf
test.o&#58; In function `main'&#58;
test.cpp&#58;&#40;.text+0x30&#41;&#58; undefined reference to `XXX&#58;&#58;Instance&#40;&#41;'
collect2&#58; ld returned 1 exit status
make&#58; *** &#91;test.elf&#93; Error 1
no wonder, i cannot see xxx.o :
psp-gcc -I. -I/opt/toolchains/psp//psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150 -L. -L/opt/toolchains/psp//psp/sdk/lib test.o
xxx.o -lstdc++ -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o test.elf

if you have N .o files so you should have them all as input files in linking stage of psp-gcc. Unless they are linked to a static library (say, xxx.a) you should add xxx.a
User avatar
Rex_VF5
Posts: 44
Joined: Wed Dec 26, 2007 6:24 am

Re: C++ compilation problem

Post by Rex_VF5 »

hlide wrote: no wonder, i cannot see xxx.o :
psp-gcc -I. -I/opt/toolchains/psp//psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150 -L. -L/opt/toolchains/psp//psp/sdk/lib test.o
xxx.o -lstdc++ -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o test.elf

if you have N .o files so you should have them all as input files in linking stage of psp-gcc. Unless they are linked to a static library (say, xxx.a) you should add xxx.a
Now I will sound stupid - but how do I do that? I tried adding xxx.o to OBJS in Makefile but that doesn't work.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

Code: Select all

PSPSDK = $&#40;shell psp-config --pspsdk-path&#41;
PSPLIBSDIR = $&#40;PSPSDK&#41;/..
TARGET = test
OBJS = test.o XXX.o
LIBS = -lstdc++

CFLAGS = -O2 -G0 -Wall
ASFLAGS = $&#40;CFLAGS&#41;

include $&#40;PSPSDK&#41;/lib/build.mak
User avatar
Rex_VF5
Posts: 44
Joined: Wed Dec 26, 2007 6:24 am

Post by Rex_VF5 »

Thank you very much. I know I deserve this post to be marked "lamer of the month" ;-)
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

Rex_VF5 wrote:I know I deserve this post to be marked "lamer of the month" ;-)
Yes , but for another reason ... For abusing C++.
Singletons & CPP = bad choise ...
User avatar
Rex_VF5
Posts: 44
Joined: Wed Dec 26, 2007 6:24 am

Post by Rex_VF5 »

PosX100 wrote:
Rex_VF5 wrote:I know I deserve this post to be marked "lamer of the month" ;-)
Yes , but for another reason ... For abusing C++.
Singletons & CPP = bad choise ...
In Java this is one of the most used patterns. Also this is part of a library - not my code. Anyway - can you tell me what would "good" C++ equivalent to singleton be and how to implement it?
Onii
Posts: 40
Joined: Sun Oct 05, 2008 1:07 pm

Post by Onii »

There's nothing wrong with using the singleton design pattern in c++. Design patterns are language agnostic anyway so I'm not exactly sure what PosX100 is talking about.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

don't worry

PosX100 is probably a C++ hater or likes to code piggy code :P.

I prefer this way :

Code: Select all

Singleton.h&#58;
class Singleton
&#123;
public&#58;
    Singleton *instance&#40;&#41;
    &#123;
        static Singleton singleton;
        return &singleton;
    &#125;

private&#58;
    Singleton&#40;&#41; &#123;&#125;
&#125;;
if I'm not wrong, g++ should be able to issue just "return &singleton;" when calling Singleton::instance() because it should instantiate "singleton();" before executing main() so "singleton" is already instantiated at the first call of Singleton::instance(). To be tested.

or you can also use only static methods if you don't need members.

EDIT:
well, apparently g++ produces something like :

Code: Select all

    Singleton *instance&#40;&#41;
    &#123;
        static instanciated = false;
        static char placeholder&#91;sizeof&#40;Singleton&#41;&#93;;
        if &#40;!instanciated&#41;
        &#123;
            new&#40;placeholder&#41; singleton&#40;&#41;;
            instanciated = true;
        &#125;
        return &#40;Singleton *&#41;placeholder;
    &#125;
i'm kinda disappointed but at least, it doesn't produce any heap allocation.
Last edited by hlide on Mon Nov 03, 2008 4:27 am, edited 1 time in total.
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

In java it makes sense , since the only available globally namespace
are classes , so this is actually a common thing to do.
(Unless you wanna build your own ref registry or use something similar with JNDI)

C++ program with singleton classes =
C program with namespace support + garbage collection.

Singleton is for lazy programmers , who are just too lazy to pass
parameters to class member function.

Now , tell me ,as far as usability goes , ... which is more usable , this:

.A.

Code: Select all


&#123;
        const float&  delta = Engine&#58;&#58;GetInstance&#40;&#41;->MotionController&#58;&#58;GetInstance->getDelta&#40;&#41;;
	Renderer&#58;&#58;GetInstance&#40;&#41;->SceneManager&#58;&#58;GetInstance&#40;&#41;->present&#40;delta&#41;;
&#125;
or THIS:

.B.

Code: Select all


&#123;
        const float& delta = engine.motionController.getDelta&#40;&#41;;
	renderer.scene.present&#40;delta&#41;;
&#125;
??

And the answer is b of course or maybe ... not?
User avatar
Rex_VF5
Posts: 44
Joined: Wed Dec 26, 2007 6:24 am

Post by Rex_VF5 »

PosX100,

while b) looks certainly nicer I wonder if it is equivalent. Main purpose of singleton pattern is to ensure only one instance of certain class exists. That is done by making constructor private and only used in singleton getter method. In your example I do not quite get how that is done but as I said earlier: I am C/C++ beginner and I already have another questions ready to be asked...
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

Code: Select all

Singleton.h&#58;
class Singleton
&#123;
	friend void __unique_singleton&#40;&#41; __attribute__&#40;&#40;constructor&#41;&#41;
	&#123;
		extern Singleton *singleton;
		static Singleton unique;
		singleton = &unique;
	&#125;

public&#58;
	// your public methods
        void doSomething&#40;&#41; &#123;&#125;

private&#58;
	Singleton&#40;&#41; &#123;&#125;
&#125;;

Singleton.cpp&#58;
Singleton *singleton;
now "singleton" should be really instantiated before running main() so you can call "singleton->doSomething();" without fear.
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

Rex_VF5 wrote: Main purpose of singleton pattern is to ensure only one instance of certain class exists.
First of all , do you really need that(ask yourself :"Do i really need that")?

For example , if you were going to program a game , there are only
a few parts of the engine that will have to be initialized once(window/graphics/sound/input).
So , their types/classes can become member variables of the head application class object.

Now , if (for example) we plan to limit the maximum instances of object "X"
rendered on screen , we can simple create a factory system with a maximum available
objects to be respawned/rendered/etc.

There is really no reason to use singleton for such thing , actually ,
there are many ways to avoid singleton-itis for any case
(actually,even instance reference counter is much better).
User avatar
Rex_VF5
Posts: 44
Joined: Wed Dec 26, 2007 6:24 am

Post by Rex_VF5 »

PosX100 wrote: First of all , do you really need that(ask yourself :"Do i really need that")?

For example , if you were going to program a game , there are only
a few parts of the engine that will have to be initialized once(window/graphics/sound/input).
So , their types/classes can become member variables of the head application class object.

Now , if (for example) we plan to limit the maximum instances of object "X"
rendered on screen , we can simple create a factory system with a maximum available
objects to be respawned/rendered/etc.

There is really no reason to use singleton for such thing , actually ,
there are many ways to avoid singleton-itis for any case
(actually,even instance reference counter is much better).
Now you're attacking the whole singleton pattern. I do not really feel myself to be that much of coding professional to argue with you. One example that comes to my mind is: you're creating a library people can use and extend. What you describe as an alternative would require people to behave properly (not calling constructor) while singleton pattern makes sure only one instance of class can be created.
PosX100
Posts: 98
Joined: Wed Aug 15, 2007 1:02 am

Post by PosX100 »

I'll give you a good example...

Lets take as example the above code:

Code: Select all

Singleton.h&#58;
class Singleton
&#123;
   friend void __unique_singleton&#40;&#41; __attribute__&#40;&#40;constructor&#41;&#41;
   &#123;
      extern Singleton *singleton;
      static Singleton unique;
      singleton = &unique;
   &#125;

public&#58;
   // your public methods
        void doSomething&#40;&#41; &#123;&#125;

private&#58;
   Singleton&#40;&#41; &#123;&#125;
&#125;;

Singleton.cpp&#58;
Singleton *singleton; 
What does it do?(or,if you like , the advantages of the pattern)
It does 4 things :
1.It enforces "lazy" creation
2.It enforces "safe" destruction
3.Allows access globally
4.Enforces the existence of a single instance(at any point in time)

So , how about breaking the thingies into a single different thingy??

You get the point i bet...
What you describe as an alternative would require people to behave properly (not calling constructor)
while singleton pattern makes sure only one instance of class can be created.
I'll ask you again , do you really need that? , answer is NO.
And why you shouldn't need such a thing? ,because you can always handle the
limit of an instance via many ways(private namespaces/private member classes in the head virtual application object/instance ref counter , ... OR , you can use patterns(such as mediator pattern for handling large projects)).
leonliu
Posts: 5
Joined: Mon Dec 15, 2008 12:39 am

Post by leonliu »

Your file test must be test.c,so the sdk choose psp-gcc to complite.you`d better use test.cpp instead of test.c
Post Reply