Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Visual Studio wants to compile my C file using C++ and fails

I have VS 2022 project, which looks like that:

main.cpp

#include <iostream>

#include "test.h"

int main()
{
     
   std::cout << "Hello World!:  " << MYTEST.a;
}

Then I use the following C – Header:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

test.h

extern "C" {
    typedef struct {
        int a;
    } TEST;

    const TEST MYTEST = {
        .a = 8 //fails here
    };
}

Unfortunately this fails with the error: "Use of designated initializers requires at least /std:c++20"

I wonder if VS tries to compile my test.h file using a cpp – compiler…

>Solution :

Your compilation unit is a .cpp file that very clearly contains C++ code, not C code. Header files are not compiled separately but simply copy-pasted into the translation unit by the preprocessor.

Also, the code in your header file is C++ as well. It wouldn’t be valid in C. extern "C" does not make C++ code to be C code. It only declares language linkage of the entities contained in the block following it. The contents of the block are still C++ code. And extern "C" itself is not valid C syntax.

So, you are writing C++, not C at all, and you need a C++ compiler. However the syntax .a = 8 in aggregate initialization is only supported since C++20 in C++. So you need to set your compiler to compile in C++20 mode or later.


Also note that in C++, in contrast to C, non-template non-volatile const variables at namespace scope have internal linkage by default. So regardless of you putting it in a extern "C" block, it won’t be visible in other translation units, e.g. a C translation unit anyway. So extern "C" there is pointless.


If your goal is to define the variable in C code, then your header should contain only the declaration

extern const TEST MYTEST;

in the extern "C" block and then you should have a .c file containing the definition

const TEST MYTEST = {
   .a = 8 //fails here
};

which you then need to compile separately as C and then link the output for the two translation units together.

Both files of course need the definition of TEST as well, so the standard approach is to include the same header file in both the .cpp translation unit and the .c translation unit, but to add extern "C" conditionally via the preprocessor:

#ifdef __cplusplus
extern "C" {
#endif
    typedef struct {
        int a;
    } TEST;

    extern const TEST MYTEST;
#ifdef __cplusplus
}
#endif
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading