Curnelious
Curnelious

Reputation: 1

Why can't I include C files in main.cpp?

I have code written in C only. The main function is main.c, and it include other c files like #include "Flash.h".

I would like to keep the project working but to be able to add a cpp file . I was told that I have to change the main to be

main.cpp

which will produce 250 errors on compilation- regarding the included c files

What's the proper way to turn the main file to cpp and still include C files ?

main.cpp :

#include "Flash.h"
int main(void)
{
....
}

I have read How to use C source files in a C++ project? which did not provide me a direct solution to the problem (my compiler will use c++ anyway).

EDIT:

Before someone will kill me for asking (don't know why you are so aggressive), I get only 3 kinds of errors 250 times :

'->' cannot appear in a constant-expression
'&' cannot appear in a constant-expression
a cast to a type other than an integral or enumeration type cannot appear in a constant-expression

EDIT 2 : Here are some of the lines ( running using SDK for some RF chip ): Most of the errors are from this section

typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
    NRF_GPIOTE_TASKS_OUT_0     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/
    NRF_GPIOTE_TASKS_OUT_1     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/
    NRF_GPIOTE_TASKS_OUT_2     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/
    NRF_GPIOTE_TASKS_OUT_3     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/
#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__)
    NRF_GPIOTE_TASKS_OUT_4     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/
    NRF_GPIOTE_TASKS_OUT_5     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/
    NRF_GPIOTE_TASKS_OUT_6     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/
    NRF_GPIOTE_TASKS_OUT_7     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/

On these lines the same error repeat :

a cast to a type other than an integral or enumeration type cannot appear in a constant-expression

Upvotes: 1

Views: 3442

Answers (2)

anatolyg
anatolyg

Reputation: 28289

The #include directive in C++ is a literal inclusion of source code. Imagine your C source code in Flash.h included by main.c doing something incompatible with C++ like

typedef int class;

Now, in your main.cpp you have

#include "Flash.h"

It's exactly as if you had this code typedef int class; directly in your C++ source file - so it's an error.


If you have C source code with C headers, you don't need to use C++ at all!

If you want to write new C++ code and make it call old code (or vice-versa), just use the linker. Have C++ code include C++ headers, and separately, C code include C headers, and the linker will combine all your code into an executable.


To make your C and C++ parts work together, you need an additional header file. For example call it c-cpp-interface.h. Then include it in all your C and C++ source files:

#include "c-cpp-interface.h" // in C files

extern "C" {
    #include "c-cpp-interface.h" // in C++ files
}

This file should be written in a common C/C++ subset language. That is, mostly, C language but with increased type safety (e.g. prototypes for all functions must be written fully, without the implied ... arguments).

Ideally, your existing C header file could be used as such. However, C header files often accumulate cruft, and it might be more practical to create a new file than clean the existing one(s).


Looking at the actual error messages you have (with offsetof), you should try to have as little code as possible in the C - C++ interface. Don't put implementation details (like values of various constants) there. Only have there the declarations/prototypes for functions that are called by the other language (C calling C++ or vice versa).

Upvotes: 5

doctorlove
doctorlove

Reputation: 19272

The question you post points out you need to wrap the inclues

extern "C" {
#include "cheader.h"
}

In your case,

extern "C" {
#include "Flash.h"
}
int main(void)
{
}

and in each cpp that wants to use C code, use extern "C" round the include.

Upvotes: 4

Related Questions