1

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
Curnelious
  • 1
  • 16
  • 76
  • 150
  • 2
    C and C++ are still two very different languages, you can't expect a header file written for a C compiler to compile flawlessly with a C++ compiler. – Hatted Rooster Jun 01 '17 at 14:25
  • 1
    Why are you mixing C and C++? No wonder it doesn't compile. You have to use `main.c` instead. – Rakete1111 Jun 01 '17 at 14:26
  • What compiler are you using? Some will auto-detect the language (C vs C++) based on the extension (e.g. `.c` vs `.cpp`). They are indeed different languages, and a C program will not necessarily compile as C++ as the languages have diverged significantly enough. – Cory Kramer Jun 01 '17 at 14:26
  • I am mixing them because I use a chip (processor for DSP), and some files are low level C, and others should be C++ app files , why is it that bad to want to write my application in C++ ? – Curnelious Jun 01 '17 at 14:27
  • You don't tell what compiler you are using. – Basile Starynkevitch Jun 01 '17 at 14:28
  • 2
    @Curnelious It isn't necesarily bad, but you must be careful compiling. Read the link that you added to your post carefully. You should compile the C code as C, and the C++ code as C++, then link them appropriately. – Cory Kramer Jun 01 '17 at 14:28
  • I am using gcc gnu99 and gnu++98 for c/c++ – Curnelious Jun 01 '17 at 14:29
  • _"I was told"_ By whom? When? Where? – Lightness Races in Orbit Jun 01 '17 at 14:32
  • _"I have read How to use C source files in a C++ project? which did not provide me a direct solution to the problem"_ because there isn't one. I think this is a straight-up dupe, tbh. – Lightness Races in Orbit Jun 01 '17 at 14:34
  • 1
    If your `Flash.h` is publicly available, give at least some link. Otherwise, give a few error messages and copy&paste into your question the few lines of `Flash.h` around them. We can't guess your error messages. – Basile Starynkevitch Jun 01 '17 at 14:37
  • 1
    You are too dramatic, I used other hardware projects before like Arduino or Pi, and mixed C++ files just like that. You are too dramatic and aggressive to me for no reason. – Curnelious Jun 01 '17 at 14:37
  • 1
    Thanks for showing some of the errors. Now, can you please show the offending line in the source code too? – Bob__ Jun 01 '17 at 14:51
  • Thanks for the extra details on the errors; if you now add example code that causes these we might be able to help – doctorlove Jun 01 '17 at 14:53
  • I have added them in another edit, but I guess I am already dead, you just killed me in a way I don't want to solve my own problem :) – Curnelious Jun 01 '17 at 14:56
  • 4
    @Curnelious You really don't need to take this stuff negatively. People are telling you how to improve your question, **so it can be answered**. These things you should add to your question are very important. You are doing the right thing including them. – anatolyg Jun 01 '17 at 15:07
  • Well, looking at the reference pages for offsetof, there can be some differences in [C](http://en.cppreference.com/w/c/types/offsetof) and [C++](http://en.cppreference.com/w/cpp/types/offsetof) implementations... – Bob__ Jun 01 '17 at 15:10
  • @Curnelious *I used other hardware projects before like Arduino or Pi, and mixed C++ files just like that.* "It worked before like that" doesn't mean it's correct. Running around outside in a lightning storm and not getting zapped doesn't make it safe. – Andrew Henle Jun 01 '17 at 15:17
  • 1
    Are there any warnings before the errors like "Not supported compiler type"? – doctorlove Jun 01 '17 at 15:20
  • @doctorlove no. Thank you for being so kind, I think I will skip on trying to mix them, it's too much for me . Thank you again. – Curnelious Jun 01 '17 at 15:52
  • 1
    Good luck - there's a chance something has gone wrong with all the macro etc in the libarary. Leave main as C and maybe have a select few things in C++ that don't need the includes from this library? – doctorlove Jun 01 '17 at 15:54
  • @doctorlove I heard this advice but I don't get it. if I leave my main to be C file, and I want to use some other C++, I will have to include it somewhere right? and if the whole code is C, it means I will have (Again) to include a C++ in a C file and back to square 1. – Curnelious Jun 01 '17 at 15:58
  • 1
    The level of indirection using a "c-cpp-interface.h" in the other answer will separate these things. – doctorlove Jun 01 '17 at 16:01
  • It seems really strange. When you do embedded, you always must have C files that some chip maker created, you can change them because there are 1000 of them. Then you want to write your application, which is complex, and it's reasonable you would like to use OOP, for your application, hence you are going to have many cpp files. I wonder how they mix them . – Curnelious Jun 01 '17 at 16:04
  • https://stackoverflow.com/a/15584711/841108 contains a useful advice: use `g++ -C -E main.cpp |grep -v '^#' > main.ii` then `g++ -Wall -c main.ii` and look at the error messages to understand what the preprocessor did. – Basile Starynkevitch Jun 01 '17 at 16:31

2 Answers2

5

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

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • How "separately" ? I have a single project, can you elaborate how to "separately" do that ? At the end I have 1 main file, this main should be using C and C++, so how would you do that ? – Curnelious Jun 01 '17 at 14:40
  • Your project should have 2 source files, `main.c` and `another.cpp`. I have never used your C/C++ system, but the concept of "project" seems pretty common for all systems - a project is a collection of source files. – anatolyg Jun 01 '17 at 14:42
  • So you have x.c and y.cpp , and you have 1 main file. You want to use both x and y in main, how would you do that ? at some point they will have to intersect, because it's the same project, and in that point you have to include a C into C++ , or the oposite . – Curnelious Jun 01 '17 at 14:44
  • you have a header with function definitions from the c side, that's in the c++ header so the linker can tell the c++ code which c function are available. that header can be common, as long as it doesn't include anything that breaks *either* c or cpp see this https://stackoverflow.com/questions/3789340/combining-c-and-c-how-does-ifdef-cplusplus-work – Jason Lang Jun 01 '17 at 14:48
4

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.

doctorlove
  • 18,872
  • 2
  • 46
  • 62
  • 3
    ... but `Flash.h` must still be valid C++. If it's not, there's no way around that other than "fixing" the header. `extern "C"` just turns off / adjusts name mangling; nothing more. It doesn't go into a sort of "C language mode". Ultimately, unless `Flash.h` is designed to be used in both C and C++, you just can't do this. They are two, distinct languages. – Lightness Races in Orbit Jun 01 '17 at 14:32
  • Thanks, just tried that, it didn't work, I have the same amount of errors as before. my main.cpp looks like I showed you, with few headers included, I put all of them in the extern C, but it didn't help – Curnelious Jun 01 '17 at 14:32
  • @BoundaryImposition really? wow, I do have 200 of them and they are really complex, no way I can change all of them , some of them are drivers. So am I stuck forever with C ? – Curnelious Jun 01 '17 at 14:33
  • 3
    @Curnelious: Impossible to tell without specific examples in the form of an [MCVE]. Where did `Flash.h` come from? Who wrote it? You could ask them about this? But, yes, in general, if you have a C program, you're "stuck forever with C" unless you (or a friend) translates the program into the other programming language that you want to use instead. – Lightness Races in Orbit Jun 01 '17 at 14:34
  • Thanks but how to be specific ? I have 280 errors that all of them comes from the C files in my program .. – Curnelious Jun 01 '17 at 14:35
  • 1
    Sorry, "how to be specific" is not an actionable question. I did provide some alternative suggestions and a link to more information on how to present programming problems. – Lightness Races in Orbit Jun 01 '17 at 14:35
  • Tell us about one of them, to start with – doctorlove Jun 01 '17 at 14:36
  • "->" can not appear in constant expression" :) – Curnelious Jun 01 '17 at 14:38
  • 2
    @Cumelious: please edit your own question, don't comment here. And as I said, give at least a few lines of `flash.h` around the exact error, and give the exact error message. If you can (& are allowed to), publish your source code somewhere. – Basile Starynkevitch Jun 01 '17 at 14:40
  • "& " can not appear in constant expression" – Curnelious Jun 01 '17 at 14:41
  • "a cast to a type other than an integral or enumeration type cannot appear in a constant-expression" – Curnelious Jun 01 '17 at 14:41
  • 3
    @Curnelious Please edit your question and add this valuable info there. There is an `edit` link on your question for that. – anatolyg Jun 01 '17 at 14:46
  • 2
    @Curnelious: please don't comment, but **edit your question** to improve it (a lot) by giving much more information. – Basile Starynkevitch Jun 01 '17 at 14:46