1

I've been struggling to solve a problem with a project I'm working on. Lets assume I have a few files:

reflection.h 
sll_insert.c
record_sll.c
io_recorder.cpp

all of the above mentioned cpp and c files use:

#include "reflection.h"

and in "reflection.h" are the following declarations:

extern void io_recorder_fun_entry(char * name, TypedObject args[], int len);

extern void io_recorder_fun_exit(char * name, TypedObject args[], int len);

These two functions are implemented in "io_recorder.cpp" and they use another function from "io_recorder.cpp" called io_record.

now, in "io_recorder.cpp", the two functions are as follows:

extern "C" void io_recorder_fun_entry(char * name, TypedObject args[], int len) {
    cout << "Entering function "<< name << endl; 
    io_record(args, len);
}

extern "C" void io_recorder_fun_exit(char * name, TypedObject args[], int len) {
    cout << "Exiting function "<< name << endl; 
    io_record(args, len);

}

When in io_record, there are calls being made to several functions declared in reflection.h and implemented in"record_sll.c"`.

I have 2 questions:

  1. The connection between C and C++ is not working for me in that case (i have experimented with it previously with other files and it seemed to work before). When trying to compile I receive errors like:

    io_recorder.cpp: In function ‘void io_recorder_fun_entry(char*, TypedObject*, int)’:

    io_recorder.cpp:61:79: error: conflicting declaration of ‘void io_recorder_fun_entry(char*, TypedObject*, int)’ with ‘C’ linkage tern "C" void io_recorder_fun_entry(char * name, TypedObject args[], int len) {

    In file included from io_recorder.cpp:4:0: reflection.h:32:13: note: previous declaration with ‘C++’ linkage extern void io_recorder_fun_entry(char * name, TypedObject args[], int len);

Obviously I did something wrong and I can't figure out what. What am I supposed to change in order for it to compile properly?

  1. In previous errors, it appeared that io_record did not recognize the functions from record_sll when I used them. Does it have anything to do with the errors from question 1? If not, what should I do to make sure io_record knows them.

Thanks in advance for the help, I hope i can fix this soon.

recursion.ninja
  • 5,377
  • 7
  • 46
  • 78
baronzo1
  • 23
  • 1
  • 5
  • 3
    You need `extern "C"` in your header declarations. – Galik Apr 16 '17 at 14:13
  • I did, and I get a different Error. reflection.h:32:8: error: expected identifier or ‘(’ before string constant extern "C" void io_recorder_fun_entry(char * name, TypedObject args[], int len); – baronzo1 Apr 16 '17 at 14:27
  • Here is a working example that may be useful: https://stackoverflow.com/questions/31903005/how-to-mix-c-and-c-correctly/31903685#31903685 – Galik Apr 16 '17 at 14:35

1 Answers1

3

From the C++ point of view, you have conflicting definition:

  • in your header you declare both function as a normal c++ function (i.e. no specific calling conventions)
  • in the body you define the fuction as using the C calling convention

This is a problem, because in all the compilation units using your header, the compiler will generate code using the c++ calling sequence, not knowing that your function bodies use another calling sequence. Hence the error message.

To solve the issue, you must declare the functions in both cases as extern "C".

From the C point of view however, the extern "C" syntax is not recognized. So if you want to use the same header for both C++ and C, some extra gym with conditional compilation is required:

#ifdef __cplusplus
extern "C" {  // this line will be compiled only if included in a .cpp file and not in a .c
#endif
    // your c function declaration go here without the extern "C"
#ifdef __cplusplus
}
#endif

You'll find additional info on mixing C and C++ on this FAQ page.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Thank you, Galik said the same thing. Look at the comment I wrote to him, I get a different error now. – baronzo1 Apr 16 '17 at 14:29
  • @baronzo1 yes, this is because when the header is included in the c file, the c language doesn't recognize this c++ syntax. Si in the header you need to use conditional compilation – Christophe Apr 16 '17 at 16:24
  • @baronzo1 I´ve edited the answer to show how to use the same header in both c an cpp files – Christophe Apr 16 '17 at 16:37
  • Yes!! I did that yesterday and it solved my problem. The #ifdef was what i needed to add to the extern "c" prefix. thanks alot! – baronzo1 Apr 17 '17 at 08:15