-1

I failed to define overloading functions with error message of error: conflicting declaration of C function if enclosing by #ifdef __cplusplus blocks.

Below is a simple code for an easy view. This piece of code worked fine without #ifdef __cplusplus blocks.

However, my project code does need #ifdef __cplusplus as it involves combination of C and C++ codes.

Command lines after #ifdef __cplusplus block should be C++, why did it fail to define the overloading function? How to fix this problem with presence of #ifdef __cplusplus blocks?

#include <iostream>
using namespace std;

#ifdef __cplusplus
extern "C"
{
#endif

int add(int x)
{
    return x;
}

int add(int x, int y)
{
    return x + y;
}

int main() {
//  cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    int X = add(2);
    int Z = add(8,2);

    cout <<X<<" "<<Z<<endl;
    return 0;
}

#ifdef __cplusplus
}
#endif
Bodo
  • 9,287
  • 1
  • 13
  • 29
wendy
  • 3
  • 2
  • 5
    But C language does not have overloading. This is a C++ feature. – heap underrun Oct 12 '22 at 08:35
  • @heapunderrun Not fully true – but a bit more [complicated](https://stackoverflow.com/a/25026358/1312382)... – Aconcagua Oct 12 '22 at 08:37
  • 2
    The problem is the `"extern "C" { ... }` which declares the functions to have C linkage. You should do this only for the declaration of C functions you want to call from C++ code or for C++ functions that will be called from C code. With C linkage you cannot have two functions with different argument lists. Unfortunately the code in the question does not show a case that would need C linkage. You should [edit] your question and show a [mre] that consists of at least a C source file and a C++ source file. – Bodo Oct 12 '22 at 08:45
  • Thank you for comments. Yes, with "extern C", it treats code as C command and overloading function is supported by C++. That is why it failed. – wendy Oct 12 '22 at 09:17
  • 1
    By the way: `using namespace std` [should be avoided](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – definitely in header files(!) – and in your case it would have needed to go inside the `#ifdef __cplusplus` section as namespaces are not available in C either – alike the `` header, which again only exists in a C++ environment. Conclusion: Your entire header isn't C-compatible anyway, so just forget about the `#ifdef __cplusplus` entirely... – Aconcagua Oct 12 '22 at 09:48
  • Hint, if you indeed want to create a header compatible for both C and C++ then create right from the start a `.cpp` file including it as well as another `.c` file doing the same and compile both with the respective compiler (e.g. g++ and gcc). – Aconcagua Oct 12 '22 at 09:51

1 Answers1

0

Command lines after #ifdef __cplusplus block should be C++

First of all, I believe you have a misconception of #ifdef __cplusplus, this macro only checks if your compiler is a C++ compiler or not.

You rather need focus on extern "C" {}. This block of code explicitly tells your compiler, that codes inside this block must be in C language(not C++).

This is important since C and C++ have different mechanisms of storing and calling functions from binary. (Called name mangling). Better to say, C and C++ binaries are not compatible. So extern "C" will tell your compiler that your functions C codes, and those function names are not mangled.

So #ifdef __cplusplus checks if your code is C or C++; if your code is in C++, insert extern "C" { that tells your compiler that those codes in this block are C code.

And since function overloading is not a part of C language, your compiler will cause an error inside that block. (This matters with name mangling).

But this macro is mostly used in header files, not source files. Because the purpose of this macro is to enable your code to be included in both C and C++ code, but source files cannot be and must not be included by another source.

Garden
  • 36
  • 5
  • Hello Jay, Thank you for comments. This macro is included in my source file so it allows to use C code. Is this correct? – wendy Oct 14 '22 at 09:12
  • Yes, `#ifdef __cplusplus` could be found here: https://en.cppreference.com/w/cpp/preprocessor/replace. By the way, `extern "C"` isn't macro but one of the feature included in C++. – Garden Oct 15 '22 at 01:08