undefined reference mit GCC



  • Hallo
    ich brauche mal wieder eure Fachkundige Hilfe
    Ich habe mit Eclipse einen Prototyp BCD.h erstellt und
    dazu BCD.c
    das meckern des Compilers

    Anmerken möchte ich das ich die Pfade bekanntgemacht habe.
    in Web
    http://stackoverflow.com/questions/5559250/c-error-undefined-reference-to-function-but-it-is-defined
    habe ich das gefunden, verstehe aber nur Bahnhof, ich kann ganz gut Englisch.
    Wie kann der Compiler das richtig linken.

    "C:\Ac6\SystemWorkbench\arduinoPlugin\tools\arduino\avr-gcc\4.9.2-atmel3.5.3-arduino2/bin/avr-gcc" -c -g -Os -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10606 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -I"C:\Ac6\SystemWorkbench\arduinoPlugin\packages\arduino\hardware\avr\1.6.14\cores\arduino" -I"C:\Users\ats37\workspace\Max7219\MyFunctions" -I"C:\Users\ats37\workspace\Max7219\MyPrototypes" -I"C:\Users\ats37\workspace\Max7219\libraries\TinyRTC" -I"C:\Users\ats37\workspace\Max7219\libraries\Max7219" -I"C:\Ac6\SystemWorkbench\arduinoPlugin\packages\arduino\hardware\avr\1.6.14\variants\mega" -I"D:\__Dokus\Documents\Arduino\libraries\LiquidCrystal" -I"D:\__Dokus\Documents\Arduino\libraries\MsTimer2-master" -I"D:\__Dokus\Documents\Arduino\libraries\TimerThree" -I"D:\__Dokus\Documents\Arduino\libraries\TimerOne-r11" -I"C:\Ac6\SystemWorkbench\arduinoPlugin\packages\arduino\hardware\avr\1.6.14\libraries\Wire" -I"C:\Ac6\SystemWorkbench\arduinoPlugin\packages\arduino\hardware\avr\1.6.14\libraries\Wire\src" -MMD -MP -MF"MyFunctions/BCD.c.d" -MT"MyFunctions/BCD.c.o" -D__IN_ECLIPSE__=1 "../MyFunctions/BCD.c" -o "MyFunctions/BCD.c.o" -Wall
    'Finished building: ../MyFunctions/BCD.c'
    ' '
    'Starting combiner'
    "C:\Ac6\SystemWorkbench\arduinoPlugin\tools\arduino\avr-gcc\4.9.2-atmel3.5.3-arduino2/bin/avr-gcc" -Os -Wl,--gc-sections,--relax -mmcu=atmega2560 -o "C:/Users/ats37/workspace/Max7219/Release/Max7219.elf" ./.ino.cpp.o ./libraries/Wire/src/utility/twi.c.o ./libraries/Wire/src/Wire.cpp.o ./libraries/TinyRTC/RTCx.cpp.o ./libraries/TimerThree/TimerThree.cpp.o ./libraries/TimerOne-r11/TimerOne.cpp.o ./libraries/MsTimer2-master/MsTimer2.cpp.o ./libraries/Max7219/DefaultFonts.c.o ./libraries/Max7219/LEDmatrix7219.cpp.o ./libraries/Max7219/LedControl.cpp.o ./libraries/LiquidCrystal/LiquidCrystal.cpp.o ./MyFunctions/BCD.c.o arduino.ar "-LC:/Users/ats37/workspace/Max7219/Release" -lm
    C:\Users\ats37\AppData\Local\Temp\ccNa7Yre.ltrans1.ltrans.o: In function main': ccNa7Yre.ltrans1.o:(.text.startup+0x4e6): undefined reference toHighNibbleWordHigh(unsigned int)'
    ccNa7Yre.ltrans1.o:(.text.startup+0x4f6): undefined reference to `HighNibbleWordHigh(unsigned int)'



  • Hallo
    Ich habe BCD.c nach BCD.cpp geändert und nun geht es kann mir jemand erklären,
    warum der Compiler so eine falsche Referenz ausgibt.



  • Das kommt davon, wenn man C und C++ mischt; nein, entgegen landläufigem Aberglauben sind C und C++ unterschiedliche Programmiersprachen.

    Der Compiler macht nichts falsch, du bedienst den (C++)Compiler falsch.

    An der Stelle, an der du du fragliche Funktion in einem cpp-Modul aufrufst, produziert der C++ Compiler gemäß seinen C++ Regeln einen Verweis auf die Funktion. Wegen Name Mangling vergibt ein C++ Compiler hier prinzipiell einen anderen (erweiterten) Namen für den Verweis als es ein C Compiler tun würde. (hängt mit dem C++ Overloading zusammen).
    In deinem C-Modul mit der Funktionsdefinition werkelt aber ein C Compiler, der vergibt als Namen dann einen reinen C Namen als Verweis für den Linker.
    Und der Linker findet dann nach der Suche in allen Modulen keine Funktionsdefinition, die auf den ursprünglichen Funktionsnamen im cpp-Modul passt und wirft deswegen korrekt 'undefined reference'.

    Eine Lösung hast du schon beschrieben: du lässt auch die Funktionsdefinition mit einem C++ Compiler statt einem C Compiler übersetzen.
    Weiterhin wäre ein C Linkage Wrapper via

    #ifdef __cplusplus 
    extern "C" {
    #endif
        HighNibbleWordHigh(unsigned int);
    #ifdef __cplusplus
    }
    #endif
    

    in deiner Header-Datei möglich, evtl. würde auch ein Umbenennen des Headers
    include.h -> include.hpp
    helfen, das wäre aber compilerspezifisch.
    Das CPP-Modul könntest/müsstest du dann wieder zu einem C-Modul umbenennen.


Anmelden zum Antworten