6

I have a project that had c files and cpp files mixed in it. The linker throws errors at me:

undefined reference to <all my functions in the c files>

After I rename all *.c files to *.cpp the errors vanish. So can't I mix those files or is this some compiler/linker options problem?


My options:

GCC C++ Compiler:

-I/usr/include/glib-2.0 -I/usr/include/gtk-2.0 -I"/myPath" -O0 -g3   \
    -Wall -c -fmessage-length=0 `pkg-config --cflags glib-2.0 gtk+-2.0

GCC C Compiler:

-I/usr/include/glib-2.0 -I/usr/include/gtk-2.0 -I"/myPath" -O0 -g3   \
    -Wall -c -fmessage-length=0 -std=c99 `pkg-config --cflags glib-2.0 gtk+-2.0`

GCC C++ Linker:

-L/usr/include/glib-2.0/glib `pkg-config --libs gtk+-2.0`

Since it says C++ Linker, does that mean object files from c files cannot be linked into the project (by default)?

dbush
  • 205,898
  • 23
  • 218
  • 273
Bitterblue
  • 13,162
  • 17
  • 86
  • 124

2 Answers2

15

You need to wrap the C code like so

extern "C" {
    #include "sample1.h"
}

A better way to do it is like in this StackOverflow question, in the C header files.

use:

#ifdef __cplusplus
extern "C" {
#endif

At the start of all C header files.

and use:

#ifdef __cplusplus
}
#endif

At the end of all C header files.

Community
  • 1
  • 1
nonsensickle
  • 4,438
  • 2
  • 34
  • 61
  • Well, in most cases this will work, but it's a bit of a kludge. It's better to carefully place the `extern "C"`s inside the header, either creating a new header for `C++` use, or detecting when you are being compiled as `C++` as described in [the question you linked](http://stackoverflow.com/q/3789340/1171191). – BoBTFish Nov 21 '13 at 10:48
  • @BoBTFish You and I have both linked to the same question. See the second link I posted. – nonsensickle Nov 21 '13 at 10:49
  • 1
    I will rephrase and fix though, better make it clear. – nonsensickle Nov 21 '13 at 10:49
  • Man, it's so hard to begin coding in C/C++ nowadays :-( Thank you, this solves a lot of problems. – Bitterblue Nov 21 '13 at 10:57
  • 2
    @mini-me Are you implying that it was easier before? – nonsensickle Nov 21 '13 at 10:58
  • Yes, it was easier before. C# and other nice languages make us lazy. – Bitterblue Nov 21 '13 at 11:00
  • @mini-me: actually, it's *incredibly simple* compared to mixing say... Python and C. Mixing languages in general is **hard**, there are only few cases where people worked on a FFI (Foreign Function Interface), which in general is just "whatever" interacting with C. – Matthieu M. Nov 21 '13 at 11:00
6

extern "C" is one approach. The other approach, assuming your C files are of the (almost ubiquitous) sort which are already compilable as C++, is simply to coerce the compiler into treating them as C++ (which gives them the appropriate name mangling to work with your C++ files). For GCC, this is -x c++.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • This looks like a better solution, doesn't it ? (since I don't have to pollute the code with wrappers), [more reference](http://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options) – Bitterblue Nov 21 '13 at 11:47
  • It depends. I say "almost ubiquitous" but there is the odd C library which has a variable named `class`... and it doesn't work for precompiled C libraries. But yeah, when it works, there's way fewer gotchas than with `extern "C"`. – Sneftel Nov 21 '13 at 11:51