3 Stimmen

GCC: Einfacher Vererbungstest schlägt fehl

Ich baue eine Open-Source-2D-Spiele-Engine namens YoghurtGum. Im Moment arbeite ich an der Android-Portierung, wobei ich das von Google bereitgestellte NDK verwende.

Die Fehler in meiner Anwendung machten mich wahnsinnig, also habe ich ein einfaches Testprogramm erstellt:

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;
}

Scheint einfach zu sein, oder? Hier ist, wie ich es kompilieren, das ist die gleiche Weise, die ich den Rest meines Codes kompilieren:

/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

(Zur besseren Übersichtlichkeit wurden Zeilenumbrüche eingefügt). Dies lässt sich gut kompilieren. Aber dann kommen wir zum 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

Wie Sie wahrscheinlich feststellen können, gibt es dort eine Menge Ballast, der nicht wirklich gebraucht wird. Das liegt daran, dass es nicht funktioniert. Es schlägt mit den folgenden Fehlern fehl:

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

Dies sind die gleichen Fehler, die ich in meiner aktuellen Anwendung erhalte.

Wenn mir jemand erklären könnte, was ich in meinem Test falsch gemacht habe oder welche Option ich in meinem Linker vergessen habe, wäre ich sehr, sehr dankbar.

Vielen Dank im Voraus.

UPDATE:

Wenn ich meine Destruktoren non-inlined mache, erhalte ich neue und spannendere Link-Fehler:

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

9voto

R Samuel Klatchko Punkte 72641

Verwenden Sie g++, um den Linker zu steuern, nicht gcc:

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

Update Ein weiteres Problem scheint die Verwendung von -nostdlib . Dadurch wird der Compiler daran gehindert, alle Standardbibliotheken hinzuzufügen (z. B. die Laufzeitbibliothek, die Ihre fehlenden Externals bereitstellt). Gibt es einen Grund, warum Sie dies benötigen?

2voto

PiotrK Punkte 3998

Versuchen Sie -fno-rtti -fno-exceptions zur g++-Befehlszeile

1voto

Puppy Punkte 141483

Sie haben versucht, in Ihrer Initialisierungsliste eine Basis zu instanziieren, von der Sie nicht geerbt haben. Car erbt nur von Vehicle und nicht auch von Base. Aus Ihrem Code entnehme ich, dass dies Ihre Absicht war.

Ich persönlich ziehe es vor, Komposition statt Mehrfachvererbung zu verwenden - das ist sauberer und leistungsfähiger.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X