1

I have 3 files with me, one c++ file, main.cpp, one c file, test.c and one header file, test.h

I wanted to try and use C code into C++ file. For the same reason, I have declared an function in test.h and defined that in test.c and using that in main.cpp

main_temp.c is just for explanation.

test.h

void test(int); 

test.c

#include <stdio.h> void test(int a) { printf("%d", a); 

main_temp.cpp

#include "test.h" int main() { foo(5); } 

Here, I understand why this would not work. C symbol would be simple 'foo' but since C++ does more things while creating symbols, it might be 'void@test(int)' and to solve this name mangling problem, I have to treat C++ symbol as a C symbol. So, I would use extern "C" and my main.cpp becomes as like:

main.cpp

extern "C" { #include "test.h" } int main() { foo(5); } 

I could not understand as to why this would not work! I get :

main.cpp:(.text+0xa): undefined reference to `test` 

Can somebody share the insights?

8
  • 2
    Did you link with test.o, and how was it compiled? Show your command line steps, or your Makefile, or CMakefile, or etc. if you're using a build system. Commented Apr 14, 2020 at 20:12
  • 1
    @aschepler, I just did : g++ main.cpp Commented Apr 14, 2020 at 20:13
  • 2
    Then you are missing test.c Commented Apr 14, 2020 at 20:13
  • 2
    So test.c isn't even a part of that program, and the definition of test really is missing. Commented Apr 14, 2020 at 20:14
  • 2
    @HemantBhargava You shouldn't use the g++ frontend to compile C files. You need to compile test.c with gcc and main.cpp with g++ and then link them together. Commented Apr 14, 2020 at 20:20

1 Answer 1

2

I trust you compile or link them together? Else that would be the cause. On gcc it would be something like:

g++ -c -o main.o main.cpp gcc -c -o test.o test.c g++ -o a.out main.o test.o 

Assuming you have no bugs with compiling/linking, compile both main.cpp and test.c into object files and run nm on both. It will show what symbol main.o wants and what symbol test.o exports. It should become clear then why linker cannot do its job.

Sign up to request clarification or add additional context in comments.

6 Comments

Lowercase -c. (And you can omit the -o x.o if you don't want a different filename or different output directory; the default is to use the same filename replacing the extension with .o)
I understand. Isn't there any way rather compile only two? Why do we need to compile separately for C and C++ files? Why can not I just do: g++ main.cpp test.c?
g++ main.cpp test.c will compile test.c as C++, not C.
g++ is the driver for the C++ compiler, but you can tell it to switch to a different language instead: g++ main.cpp -x c test.c. The -x flag means "files later on the command line use this specific language".
@MilesBudnek • For C, you should use a C compiler. For C++, you should use a C++ compiler. If you were to have FORTRAN in the mix, the for FORTRAN you should use a FORTRAN compiler.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.