0

I have a very specific case of Linker error :

'Invoking: GCC C++ Linker 4 [arm-linux-gnueabihf]' arm-linux-gnueabihf-g++ -lpthread ./src/FPGA_Peripherals/AUX_IMU/AUX_IMU_functions.o
./src/main.o: In function main': ../src/main.cpp:7: undefined reference to `function()'

the error output is truncated for purpose of this post. The error and the object, where the function definitions lies, is highlighted.


The code is compiled and linked using DS-5 C/C++ Eclipse Platform, with the GCC 4.x [arm-linux-gnueabihd] (DS-5 built-in) tool-chain :

  • GCC C++ Compiler 4 [arm-linux-gnueabihf]
  • GCC C Compiler 4 [arm-linux-gnueabihf]
  • GCC Assembler 4 [arm-linux-gnueabihf]
  • GCC C Linker 4 [arm-linux-gnueabihf]
  • GCC C++ Linker 4 [arm-linux-gnueabihf]
  • GCC Archiver 4 [arm-linux-gnueabihf]

With Gnu Make Builder.


Source code is structured in folders :

  • src

    main.cpp

    • FPGA_peripherals

      • AUX_IMU

      header.h

      AUX_IMU_functions.c


Minimalistic code producing the error :

main.cpp

#include "header.h" int main() { function(); return 0; } 

header.h

void function(void); 

AUX_IMU_functions.c

#include "header.h" void function(void){ int i = 3; }; 

The C code is correctly compiled using GCC C Compiler 4 [arm-linux-gnueabihf]. The C++ code (other files, not included within this example), are correctly compiled using GCC C++ Linker 4 [arm-linux-gnueabihf].


This apparently is not a Linker related problem, but what else to check, if Linker still produces this error ?


The error disappears, once I re-name the files to .hpp and .cpp. Why is that ? Does GCC C and GCC C++ produces incompatible .o objects ?

3
  • Note that the final semicolon in void function(void){ int i = 3; }; is superfluous. Almost, but not quite harmless; under strict compiler options, you'll get a warning about an empty global declaration, which will probably confuse you. Initializers and types need a semicolon after the close brace; functions do not. Commented Jan 13, 2018 at 10:47
  • Your error occurs because of C++ type-safe linkage which mangles function names. You need to tell the C++ compiler that the function() has C linkage: extern "C" void function(void);. You normally do that by using #ifdef __cplusplus / extern "C" / #endif before the function declaration, or use the extern "C" { before and } conditionally after a block of C function declarations. Commented Jan 13, 2018 at 10:48
  • @JonathanLeffler well, it is a constraint violation, so the compilation is allowed to fail. Commented Jan 13, 2018 at 10:57

1 Answer 1

0

Your error occurs because of C++ type-safe linkage, which mangles function names. You need to tell the C++ compiler that the function() has C linkage:

extern "C" void function(void); 

However, if the same header should be used by both the C and C++ compilers, you normally do that by using

#ifdef __cplusplus extern "C" #endif void function(void); 

for a single function declaration, or use

#ifdef __cplusplus extern "C" { #endif void function(void); int response(int arg); … #ifdef __cplusplus } #endif 

around a block of function declarations for functions with C linkage.

You can also use your existing header in C, and in your C++ code, use:

extern "C" { #include "header.h" } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I have actually tried to use 'extern "C" ' before, but it produces other error, because of the GCC C compiler, which doesnt recognizes it. Now I understand why it is so vital to add the #ifdef _cplusplus

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.