-2

This may be a bit of a long shot...

I have a C project and want to include a C++ file however I am getting an error with the following code:

//GPIO_CPP.cpp

class GPIO
{
    public:
        uint32_t Port;
        uint32_t Pin;
};

#ifndef __cplusplus
    #error  Enable CPP compilation
#endif

This inluded in my main.c as follows:

//main.c

#include "GPIO_CPP.cpp"

Error:

Error[Pe020]: identifier "class" is undefined

I have also tried putting this in a header file with .h and .hpp extensions with the same behaviour.

I've placed a compiler check:

#ifndef __cplusplus
    #error  Enable CPP compilation
#endif

which is firing.

My compiler options:

Image of compiler setting

regimon
  • 1
  • 4
  • 2
    Your C project is probably compiling the file as C. `class` is a C++ keyword. – Eljay Oct 01 '19 at 17:00
  • Hello Eljay. Yes i suspect this too. However with the IAR compiler option 'Auto (extension-based)' it should pick up this file as C++ as it has a .cpp extension. – regimon Oct 01 '19 at 17:03
  • With this limited information I am not able to reproduce the problem. Please provide a [mcve]. – Johan Oct 02 '19 at 06:45
  • What do you mean by *"want to include a C++ file"*? Are you literally trying to `#include "GPIO_CPP.cpp"` into your C file? As others have stated, please create [mcve]. – user694733 Oct 02 '19 at 07:53
  • I have updated the question. I am including the.cpp directly in main.c. – regimon Oct 02 '19 at 09:12
  • According to the extension main.c is compiled as c-code. This implies that the content of all included files also are compiled as c-code since `#include "GPIO_CPP.cpp"` works as if the text contained in GPIO_CPP.cpp was written in main.c – Johan Oct 02 '19 at 09:19
  • @Johan I see. I am guessing that there is no equivalent of extern "C" for including cpp files from a c project. Meaning the only way to do this is transition to a main.cpp project and extern "C" all C files? – regimon Oct 02 '19 at 09:25
  • One thing that stands out here is that you `#include` source files (`.c` and `.cpp`), and not header files. That should not be done, especially if you are mixing C and C++ code. `extern "C"` only tells C++ compiler to C naming scheme for linkage, but doesn't protect you subtle differences when you try to compile seemingly compatible C code with C++ compiler. – user694733 Oct 02 '19 at 10:56
  • @user694733 I am aware of this, I wanted to rule out the possibility of the compiler not recognising the source file as C++. It is not clear to me how the compiler handles header files when in auto mode. The totally of the documentation on this option in the manual is: _Automatic If you select Automatic, language support is decided automatically depending on the filename extension of the file being compiled:●Files with the filename extension c will be compiled as C source files●Files with the filename extension cpp will be compiled as Extended Embedded C++ source files._ – regimon Oct 02 '19 at 11:11
  • *"It is not clear to me how the compiler handles header files when in auto mode."* It doesn't. Extension of included file can be anything. `#include` simply copies contents from header to parent file, and results are parsed as part of parent file, using the language rules of compiler you are compiling the parent file with. – user694733 Oct 02 '19 at 11:21
  • Just to clarify, my comment above applies regardless of the Language setting, and also for all compilers other than IAR too. – user694733 Oct 02 '19 at 11:26
  • The `#include` preprocessor directive just includes the file verbatim (and then does preprocessor macro expansion). You could have a Pascal source `#include "foo.pas"` or Fortran `#include "bar.f"`, but the entirety of the `main.c` translation unit will be compiled as C. The C compiler does not understand C++ any better than it understands Pascal or Fortran. – Eljay Oct 02 '19 at 11:35
  • Ok I understand what you are meaning. However the utility of the Automatic setting is still opaque to me when using a C project. What's confusing me is this source: https://www.iar.com/support/tech-notes/compiler/mixing-c-and-c/ _... Alternatively, you want to call C++ functions from your C project. ... Use C-linkage. Put extern "C" { // your function declarations } in header files. Note that this is required for both C++ and C header files: For a C function to be able to call a C++ function._ – regimon Oct 02 '19 at 11:51
  • _extern "C"_ is not available to the C Compiler. So if you include a C++ file in a C translation unit it wont work? – regimon Oct 02 '19 at 11:55

1 Answers1

1

Assuming you are trying to include C++ module in C project, best way to do this is this:

gpio.h

#ifndef GPIO_H
#define GPIO_H

// Types accessible to C and C++ modules

struct GPIO
{
    uint32_t Port;
    uint32_t Pin;
};

// Functions accessible to C and C++ modules.
// Use extern "C" only when included to C++ file.
#ifdef __cplusplus
extern "C" {
#endif
void foo(uint32_t x);
#ifdef __cplusplus
}
#endif

// Functions accessible to C++ modules only.
// These functions not visible if included to C file.
#ifdef __cplusplus
void bar(uint32_t x);
#endif

#endif

gpio.cpp

#include "gpio.h"

// extern "C" declaration must be visible to this definition to compile with C compatible signature
void foo(uint32_t x) {
    // It's OK to call C++ functions from C compatible functions, 
    // because this is C++ compilation unit.
    bar(x);
}

// This function can be called only from C++ modules
void bar(uint32_t x) {
    // It's OK to call C compatible functions from C++ functions
    foo(x);
}

main.c

#include "gpio.h"

// Use only C compatible types (struct GPIO) and functions (foo) here
int main(void) {
    foo(1); // ok, because of extern "C"
    bar(1); // invalid because this is C file
}

Add main.c and gpio.cpp to your project tree, and make sure Language setting is set to Auto.

user694733
  • 15,208
  • 2
  • 42
  • 68