1

I am mostly programming in C, yet some of my code is in C++. The code compiles fine using gcc/g++ under Linux, yet VisualStudio Code's IntelliSense is reporting include errors with the following setup:

// file1.c
#include "includefile1.h"

IntelliSense reports

#include errors detected. Please update your includePath. Squiggles are disabled for this translation unit.

cannot open source file "atomic" (dependency of "includefile1.h"). Please run the 'Select IntelliSense Configuration...' command to locate your system headers.

The includefile1.h is written in C++ and would include things like

// includefile1.h
#include <atomic>

Compiling works fine, yet the IntelliSense errors are bothering me when working with VSCode.

  • Is there a fix to that?
  • Is there something I can add to the c_cpp_properties.json to point IntelliSense to the correct paths?
  • Do I have to adjust something else, given that I am mixing C and C++?
8
  • 1
    You should ensure that all C++ headers are in their own directory which is not added to the "C" include directories. Or even better you should have a seperate translation unit for your "C" code AND a seperate one for your "C++" code (e.g. two different static libs) where the C++ one can depend on the "C" one but not the other way around. Commented Oct 26 at 13:40
  • 1
    When the compiler finds a #include directive, it replaces the directive with the contents of the included file, effectively pasting the the included file into the including file. Once all of the preprocessing is done, the combined file is compiled. So what you have here is a C file containing C++ code being processed by a C compiler.In some compilers the line between C and C++ is very blurry. GCC for example uses the same compiler back end for both C and C++, so the earliest you're likely to find problems is when the program links. Commented Oct 27 at 1:53
  • Thank you, @PepijnKramer ! While I am contributing to the project, I am not really in a position to push for organisational or structural changes to the code base. And the code compiles and runs fine. I just hoped to find a solution to stop IntelliSense complaining about it. Commented Oct 27 at 9:38
  • 1
    Well you write #include "blabla, without the closing double quote. Can the problem be this? Commented Oct 27 at 9:56
  • 2
    Well, I don't know about your organization structure. But I assume/hope you have a techlead/architect who at least might be willing to listen (even if he/she cannot prioritize those changes to happen quickly). Commented Oct 27 at 10:02

2 Answers 2

5

You should not include C++ headers into C code. That can lead to some very strange bugs.

If you really need to mix C and C++ code in the same project, then you can do a distinction:

  • C code and headers should be stored in *.c and *.h
  • C++ code and headers in *.cpp and *.hpp

This way you will not mix them yourself accidentally. And you would be able to tell VSCode how to recognize these two languages and not mix them. You would not be able to rename headers from external libraries, of course, but you can wrap such includes into your own headers:

// externalLibraries.hpp
#include <somelib.h>
#include <otherlib.h>

Just keep .hpp in your project tree for your own plus-plus headers and a lot of problems will disappear.


It is indeed possible to modify c_cpp_properties.json and include there proper include paths:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${default}",
                "/usr/local/someExternal/library/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

The only issue with c_cpp_properties.json is that it belongs to a workspace and you need to repeat it for each individual project you are working on. But it still can be preferable, if your projects should have different compilers/includePaths/defines...

Or you can use a global settings.json which works on all projects at the same time and add include paths there:

    "C_Cpp.default.includePath": [
        "C:\\msys64\\ucrt64\\include\\glib-2.0",
        "C:\\msys64\\ucrt64\\include\\libxml2"
    ]
Sign up to request clarification or add additional context in comments.

5 Comments

When you make a header file to be usable in both C and C++ you need to apply special care in making it compilable on both languages. But recommending not doing that is running against one of the designing principles of design in c++ (read Stroustrup’s rationale) so it’s frequent to see libraries ( mainly standard c library) to incorporate such measures. Don’t recommend that.
Please, be more careful while reading. I never said "C in C++", I said "C++ in C". And TC is also doing "mostly programming in C, yet some of my code is in C++". Your righteous indignation is completely misplaced. Not for the first time. You already killed at least four of my answers just from the similar misakes.
I have never read about the convention you say about putting a .hpp suffix to c++ files. I have read about using it for files that are to be used exclusively in C++ language. C++ was designed to colive with C Code. But C was not. Once you know this you will have no trouble in distinguishing that and you’ll never need to recommen this.
Yes, .hpp is used exclusively in C++ language. Specially for headers. My first encounter with such extension was in 1993, while working with Borland C++ in a library which would later become VCL. It is used in several open source projects, most modern FAR2L. Yes, it is not a very well-known convention, but it exists.
That's not an extension. I’ve not seen it ever in stroustrup’s book. Only in Microsoft derived code. Stroustrup is more inclined to use no extension at all, so he comments about stdio.h -> cstdio, or iostream
4

The includefile1.h is written in C++

That's not the way it works. Header files are effectively written in whatever language the files they are included in are compiled in because, conceptually, they are included directly in the text of the file to be compiled before it is compiled.

So, if file1.c is compiled with the C compiler, all the header files it includes will also be compiled with the C compiler and, of course #include <atomic> is unlikely to work with C.

Your options:

  • compile file1.c with the C++ compiler
  • rewrite includefile1.h to be in C - probably #include <atomic.h> might work.
  • conditional compilation

The first option might not work because C++ is not a strict superset of C. The second option might be a lot of work if there is a lot of C++ in the header file.

The third option involves using the standard macro __cplusplus which is defined for C++ but not for C.

// includefile1.h

#if defined __cplusplus
// C++ stuff
#else
// C equivalents to the C++ stuff
#endif

2 Comments

Thank you for your explanation, @JeremyP! The code compiles and runs fine. It's just that IntelliSense is complaining about having this mixture of languages (with which GCC does not seem to have an issue), and I would like to get rid of the squiggly lines and get useful comments from IntelliSense about the code itself, without having to refacture, restructure, or reorganise the code base.
Intellisense is giving correct reports here. gcc is maybe not compiling the file as C, or it has extensions enabled in it, that allows C++ staff in the headers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.