#6806 - mpowell - Tue Jun 03, 2003 1:38 am
Has anyone ever used templates with gcc for GBA. I can compile, but linking always gives me errors like the following...
main.o:/cygdrive/c/Test/main.cpp:85: undefined reference to `operator new[](unsigned long)'
main.o:/cygdrive/c/Test/main.cpp:85: undefined reference to `operator delete[](void*)'
main.o:/cygdrive/c/Test/main.cpp:85: undefined reference to `operator delete(void*)'
main.o:/cygdrive/c/Test/main.cpp:83: undefined reference to `vtable for __cxxabiv1::__class_type_info'
main.o:/cygdrive/c/Test/main.cpp:85: undefined reference to `operator delete[](void*)'
main.o:/cygdrive/c/Test/main.cpp:85: undefined reference to `operator delete(void*)'
I'm thinking I'm not using the right compiler switches, or that the elf gcc compiler doesn't handle them properly or something. I'm using a very simple test program (below) to try and see if they work. Any ideas?
template<class T, int stackSize>
class Stack
{
public:
Stack();
virtual ~Stack();
};
template<class T, int stackSize>
Stack<T, stackSize>::Stack()
{
}
template<class T, int stackSize>
Stack<T, stackSize>::~Stack()
{
}
int main()
{
Stack<int, 8> test;
}
#6808 - GbaGuy - Tue Jun 03, 2003 1:44 am
I'm not absolutely sure what you need, but maybe try linking with
libstdc++.a and libsupc++.a .
#6855 - mpowell - Tue Jun 03, 2003 5:01 pm
That was it!
I just had to add -lstdc++ at the end of my link command in my make file.
What specifically does stdc++.a and libsupc++.a add as functionality?[/b]
#6863 - Jason Wilkins - Tue Jun 03, 2003 8:06 pm
You should use g++ instead of gcc, and it will add libstdc++ and libsupc++ automatically.
libstdc++ adds a whole slew of functions needed to support basic c++ operations and c++ standard library functions like set_new_handler.
_________________
http://devkitadv.sourceforge.net
#6870 - GbaGuy - Tue Jun 03, 2003 10:13 pm
I didn't even notice that it wasn't G++!
I didn't know GCC would compile c++ operators...
#6871 - mpowell - Tue Jun 03, 2003 10:46 pm
I've now changed it to g++ without listing the libs and it works fine too.
Thanks!
#6872 - mpowell - Wed Jun 04, 2003 12:47 am
ok, now that I've put split out the template stack into a .h and .cpp file it gives me my undefined reference errors again!
/cygdrive/c/Test/main.cpp:11:undefined reference to `Stack<int, 8>::Stack()'
/cygdrive/c/Test/main.cpp:11: undefined reference to `Stack<int, 8>::~Stack()'
I added -freop flag to g++ compile to Enable automatic template instantiation, but it didn't help. I even tried adding the -lstdc++ and -lsupc++ flags on the link but it didn't help either...
I've tried -fimplicit-templates flag too, but I'm not sure what "Emit implicit instatiations if needed" means.
#6930 - mpowell - Wed Jun 04, 2003 5:57 pm
Is the crt0.s file important in any C++ operations? Do you need a special one for C++?
#6941 - Jason Wilkins - Wed Jun 04, 2003 8:20 pm
I would guess that 'emit implicit templates if needed' means that it will automatically emit implicitly instantiated templates (duh! ^_^). If you explicitly instantiate all your templates, then I do not think it will do anything. Sounds to me like this feature is designed to help prevent errors, because you can end up instantiating a template without realizing it.
I do not think that gcc supports seperating the template definitions form the template declaration at this point, so you will need to use the "Borland Model" as described on this page http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC110 and put them together in one file. If you want to reduce compile times, go ahead and use the -repo flag. But, according to this page you still have to put make sure that each translation unit can see the entire template definition.
Or, it appears that you can use the -NO-implicit-templates, and then create single file which includes your .c file and explicitely creates a single instance of each type you are using.
Code: |
#include "stack.h"
#include "stack.cpp"
// create a dummy instance of each type you are going to use
|
Read all of that page I linked for more details. I'm glad you ask this question, because I had not thought about this issue much and was doing this the old way, which can be wasteful.
About crt0.S...
DKA4 or DKA5 do not do anything special to support C++ in crt0.S, except that DKA4 calls main, which triggers gcc to link in __gccmain, which does C++ stuff. DKA5 calls AgbMain, which is defined in libc as a function which calls constructors, destructors, and exit. This is more flexible because it allows you to override AgbMain and cut out all that C/C++ stuff if you do not need it (or, you can override it to provide a main that can recieve command line arguments and other features which are outside the scope of DKA).
_________________
http://devkitadv.sourceforge.net
#6947 - mpowell - Thu Jun 05, 2003 12:03 am
Thanks, I had read this page... I just didn't understand it! I will read it again and see if it sinks in farther.
Tell me if this is correct or not... basically you include the header and implementation into all files that use it, they will get compiled into each of those file's .o files, then the linker will toss multiple versions of them?
I still don't know exactly what the repo flag is used for. Is it to toss out the multiple versions or is that automatic?
#6954 - Jason Wilkins - Thu Jun 05, 2003 6:07 am
The compiler will NOT toss extra versions of it unless you use the -repo flag. The -repo flag tells the compiler to keep track of all the different versions by using .rpo files, which the linker can then use to identify identical copies.
You compile the code in the 'traditional' way, which they are calling 'borland', where you have to include the implementation of each template with each translation unit. The -repo flag is used with that method to eliminate duplicate code, but it works without that flag too (your executable will be bigger however).
Read that web page very carefully! It explains exactly what is going on, and does a fairly good job of it too. I could only confuse you by misintrepreting it because I have not done anything with templates except the old 'borland' method, which involves no special flags. I have only ever done templates by including all the template code in a .h file and live with the extra baggage because I have only ever used C++ on a PC. I will need to learn to use this however, because you really can't afford all that extra code size on the GBA.
I also noticed that when using STL, the compile times are MUCH longer than with a normal C program. I bet that it could be a lot faster if I could figure out a way not to recompile the template code for every C++ file (this could be a big problem). I think the only way would be to wrap STL containers in an interface, and then compile that interface file once.
_________________
http://devkitadv.sourceforge.net