Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C compiling - 'undefined reference to function' when trying to link object files

Tags:

c

so i create the object files with

cc -c MAIN.C
cc -c tablero.c

but then when i try to link them to an executable with

cc MAIN.o tablero.o

i get

undefined reference to `asdf()'

(function defined in tablero.c and called in MAIN.C)

here are my files:

i have MAIN.C

#include <stdio.h>
#include <cstring>
#include "tablero.h"
int main()
{
   int c;
   printf( "Enter a value :");
   c = getchar( );
   putchar(c);
   printf( "\nYou entered: ");
   c = asdf ();
   putchar(c);
   return 0;
}

i have tablero.h

#ifndef TABLERO_H_
#define TABLERO_H_
int asdf();
#endif // TABLERO_H_

and i have tablero.c

#include "tablero.h"
int asdf() {return 48;}; //48 is 0 in ascii
like image 678
Jose V Avatar asked Apr 23 '17 19:04

Jose V


People also ask

How do you fix undefined reference error in C?

When we compile these files separately, the first file gives “undefined reference” for the print function, while the second file gives “undefined reference” for the main function. The way to resolve this error is to compile both the files simultaneously (For example, by using g++).

How do you fix undefined references to Main?

To fix this error, correct the spelling of the main() function.

How do you fix undefined symbol in C++?

Generating an Executable Output File Similarly, if a shared object is used to create a dynamic executable and leaves an unresolved symbol definition, an undefined symbol error results. To allow undefined symbols, as in the previous example, use the link-editor's -z nodefs option to suppress the default error condition.

What causes undefined reference in C++?

A likely cause for the "undefined reference" is that the compilation and link phase are being done with the gcc compiler instead of the g++ compiler. To confirm this, set the environment variable ATTOLSTUDIO_VERBOSE to 1 or within the GUI go to Edit -> Preferences -> Project and make sure "Verbose output" is checked.


1 Answers

You have been bitten by an obscure feature of the cc tool on many Unixy systems: files whose suffix is lowercase .c are compiled as C, but files whose suffix is uppercase .C are compiled as C++! Therefore, your main (compiled as C++) contains an external reference to a mangled function name, asdf() (aka _Z4asdfv), but tablero.o (compiled as C) defines only an unmangled name, asdf.

This is also why you were able to include the C++ header file <cstring> in what was meant to be a C program.

Rename MAIN.C to main.c (and change <cstring> to <string.h>), recompile main.o, and your program should link.

If you actually want to compile part of your program as C and part as C++, then you can annotate your header files with extern "C" to make the symbols match up:

#ifndef TABLERO_H_
#define TABLERO_H_

#ifdef __cplusplus
extern "C" {
#endif

int asdf(void);

#ifdef __cplusplus
}
#endif

#endif // TABLERO_H_

Header files like this have to be extra careful to contain only code that has the same meaning in C and C++. Only POD types, no C++ keywords, no C99-but-not-C++ keywords either, no overloads, et cetera.

like image 53
zwol Avatar answered Sep 20 '22 17:09

zwol