开发者

GCC: Simple inheritance test fails

开发者 https://www.devze.com 2022-12-28 23:33 出处:网络
I\'m building an open source 2D game engine called YoghurtGum. Right now I\'m working on the Android port, using the NDK provided by Google.

I'm building an open source 2D game engine called YoghurtGum. Right now I'm working on the Android port, using the NDK provided by Google.

I was going mad because of the errors I was getting in my application, so I made a simple test program:

class Base
{

public:

    Base() { }
    virtual ~Base() { }


}; // class Base

class Vehicle : virtual public Base
{

public:

    Vehicle() : Base() { }
    ~Vehicle() { }


}; // class Vehicle

class Car : public Vehicle
{

public:

    Car() : Base(), Vehicle() { }
    ~Car() { }

}; // class Car

int main(int a_Data, char** argv)
{
    Car* stupid = new Car();

    return 0;
开发者_运维技巧}

Seems easy enough, right? Here's how I compile it, which is the same way I compile the rest of my code:

/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-g++
-g 
-std=c99 
-Wall 
-Werror 
-O2 
-w 
-shared 
-fshort-enums 
-I ../../YoghurtGum/src/GLES 
-I ../../YoghurtGum/src 
-I /home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/include 
-c src/Inheritance.cpp 
-o intermediate/Inheritance.o

(Line breaks are added for clarity). This compiles fine. But then we get to the linker:

/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc
-lstdc++ 
-Wl,
--entry=main,
-rpath-link=/system/lib,
-rpath-link=/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib,
-dynamic-linker=/system/bin/linker,
-L/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0,
-L/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib,
-rpath=../../YoghurtGum/lib/GLES 
-nostdlib 
-lm 
-lc 
-lGLESv1_CM  
-z 
/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o 
/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtend_android.o
intermediate/Inheritance.o 
../../YoghurtGum/bin/YoghurtGum.a 
-o bin/Galaxians.android

As you can probably tell, there's a lot of cruft in there that isn't really needed. That's because it doesn't work. It fails with the following errors:

intermediate/Inheritance.o:(.rodata._ZTI3Car[typeinfo for Car]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
intermediate/Inheritance.o:(.rodata._ZTI7Vehicle[typeinfo for Vehicle]+0x0): undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info'
intermediate/Inheritance.o:(.rodata._ZTI4Base[typeinfo for Base]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
collect2: ld returned 1 exit status
make: *** [bin/Galaxians.android] Fout 1

These are the same errors I get from my actual application.

If someone could explain to me where I went wrong in my test or what option or I forgot in my linker, I would be very, extremely grateful.

Thanks in advance.

UPDATE:

When I make my destructors non-inlined, I get new and more exciting link errors:

intermediate/Inheritance.o:(.rodata+0x78): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
intermediate/Inheritance.o:(.rodata+0x90): undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info'
intermediate/Inheritance.o:(.rodata+0xb0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
collect2: ld returned 1 exit status
make: *** [bin/Galaxians.android] Fout 1


Use g++ to drive the linker, not gcc:

/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-g++
-Wl,
--entry=main,
...

Update: another problem appears to be your use use of -nostdlib. This is stopping the compiler from adding all the standard libraries (such as the runtime library that provides your missing externals). Is there a reason you need this?


Try adding -fno-rtti -fno-exceptions to g++ command line


You tried to instantiate in your initialization list a base you didn't inherit from. Car only inherits from Vehicle and not also Base. From your code I assume that was your intention.

I personally prefer to use composition rather than multiple inheritance - it's cleaner and better performance.

0

精彩评论

暂无评论...
验证码 换一张
取 消