GCC: Simple inheritance test fails

10,950

Solution 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?

Solution 2

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

Solution 3

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.

Share:
10,950
knight666
Author by

knight666

Game programming student at IGAD.

Updated on June 04, 2022

Comments

  • knight666
    knight666 almost 2 years

    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