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 CompilersAnmerken 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 functionmain': ccNa7Yre.ltrans1.o:(.text.startup+0x4e6): undefined reference to
HighNibbleWordHigh(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.