Reputation: 89
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:
Is the program not compiling because C does not support function overloading?
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
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
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
Reputation: 238401
- Is the program not compiling because C does not support function overloading?
Correct.
- 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