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 ?

  • 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. – Jonathan Leffler Jan 13 '18 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. – Jonathan Leffler Jan 13 '18 at 10:48
  • @JonathanLeffler well, it is a constraint violation, so the compilation is allowed to fail. – Antti Haapala -- Слава Україні Jan 13 '18 at 10:57

1 Answers1

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"
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 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 – new_stacker Jan 13 '18 at 11:24