1

I have previously written an overloaded function in C++ code and I now need to call that function from a C file. Unfortunately, after I include the c++ header in C, Makefile does not compile. (Am using g++ w/ c++11 flag)

Here are my questions:

  1. Is the program not compiling because C does not support function overloading?

  2. If (1) is the case, what are some other options I can take to use the overloaded function?

cplusplus.h

#ifndef CPLUSPLUS_H
#define CPLUSPLUS_H

#ifdef __cplusplus
 extern "C" {
"#endif"

void Foo(A a);
void Foo(B b);

#ifdef __cplusplus
 }
"#endif"


cplusplus.cxx

#include "cplusplus.h"

extern "C" {

   void Foo(A a) {
      print(a.some_member);
   }

   void Foo(B b) {
      print(b.some_member);
   }
}


main.c

#include "cplusplus.h"

int main(int argc, char*argv[]) {
   return 0; //Even without calling the function, an error throws.
}
Mikan
  • 89
  • 8
  • 5
    C does not support overloading of functions. – Andrew Henle Jul 22 '19 at 21:50
  • 1
    Yes, C does not support overloading. As such, when you include "cplusplus.h" into your C source file, you are including code that is not legal C code and cannot compile. – Christian Gibbons Jul 22 '19 at 21:51
  • 2
    For your sanity, pretend that C is python and C++ is JS. You can't mix python and JS just like you can't (you can but were pretending) mix C and C++. – NathanOliver Jul 22 '19 at 21:51
  • Probable dupe: https://stackoverflow.com/questions/2351792/does-c-support-overloading I'll refrain from voting to close as the closure will be immediate were I to vote. – Andrew Henle Jul 22 '19 at 21:51
  • If you really want something that is like overloading, you can try to make use of C11's `_Generic`, but it will still take some reworking of your C++ code to make it work. – Christian Gibbons Jul 22 '19 at 21:53
  • *after I include the c++ header in C* -- You're doing things wrong. You should be including the original `C` header file, and then adjusting it with `extern C`. You shouldn't be creating new functions as you seem to be doing (the original C code probably did not have overloads in it). – PaulMcKenzie Jul 22 '19 at 21:53
  • @NathanOliver not a great analogy as it is possible to mix C and C++ within the same project. And in fact this is a good approach to combine pre-existing C code with new C++ code (say you download a public domain crypto library in C for example). – M.M Jul 24 '19 at 06:43

3 Answers3

3

Is the program not compiling because C does not support function overloading?

Yes.

If (1) is the case, what are some other options I can take?

The C interface must use function names that are not overloaded and does not use any other incomatible C++ artifacts. For example, you can't use reference types in the extern "C" functions.


// C++ functions
void Foo(A a) {
   print(a.some_member);
}

void Foo(B b) {
   print(b.some_member);
}

// C-compatible layer.
extern "C" {

   void Foo_A(A a) {
      Foo(a);
   }

   void Foo_B(B b) {
      Foo(b);
   }
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
3
  1. Is the program not compiling because C does not support function overloading?

Correct.

  1. If (1) is the case, what are some other options I can take to use the overloaded function?

If you only need to call one of the functions, then you can write a separate header for it, so that you can declare it without the other overload.

If you need to call both, then you can write wrapper functions with different names that offers a C compatible API.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

C does not support C++'s overloading, but the C11 standard did bring in its own flavor that you can use with the help of some wrapper functions.

First let's start with a basic cpp source file with an overloaded function that prints the value passed into it:

foo.cpp

#include "foo.h"

#include <cstdio>

void Foo(int a) {
    printf("%d\n", a);
}

void Foo(float b) {
    printf("%f\n", b);
}

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

// wrapper functions for use in C
void FooA(int a) {
    Foo(a);
}

void FooB(float b) {
    Foo(b);
}

#ifdef __cplusplus
}
#endif // __cplusplus

Now with the header file here we perform a little generic macro magic to make overloading work in C.

foo.h

#ifndef FOO_H
#define FOO_H

// C can't handle these overloaded functions, so only let C++ see them
#ifdef __cplusplus
void Foo(int a);
void Foo(float b);

// C++ won't be needing these wrappers
#else
void FooA(int a);
void FooB(float b);

// Where the magic happens
#define Foo(X) _Generic((X), \
    int: FooA((X)), \
    float: FooB((X)) \
)
#endif // __cplusplus
#endif // FOO_H

And a simple C file to prove it works

main.c

#include "foo.h"

int main(void) {
    int x = 4;
    float y = 3.2f;

    Foo(x);
    Foo(y);
}

compile our sources and it comes out cleanly with no warnings

gcc -Wall -Wextra -Wpedantic -std=c11 -c main.c -o main.o
g++ -Wall -Wextra -Wpedantic -std=c++11 -c foo.cpp -o foo.o
gcc  -o bin main.o foo.o

run it and we get:

$ ./bin
4
3.200000

So there it is, with just a little bit of work in your header file, you can use your overloaded functions in your C sources as you would your C++ sources.

Christian Gibbons
  • 4,272
  • 1
  • 16
  • 29