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:
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