Mikan
Mikan

Reputation: 89

Using overloaded c++ function in c

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.
}

Upvotes: 1

Views: 747

Answers (3)

Christian Gibbons
Christian Gibbons

Reputation: 4370

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.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206667

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);
   }
}

Upvotes: 3

eerorika
eerorika

Reputation: 238401

  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.

Upvotes: 4

Related Questions