This is a part of a huge project, so I post an excerpt from a cc file (only one static_assert is needed in the real code, I just experimented with it):
namespace large
{
static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); // A
namespace fake_n
{
static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); // B
}
class fake_c
{
static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); // C
};
void fake_f()
{
static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); // D
}
} // namespace large
gcc9 reports the following errors (correspondingly in A,B,C,D cases):
A,B : error: expected constructor, destructor, or type conversion before '(' token
C : error: expected identifier before 'sizeof'
: error: expected ',' or '...' before 'sizeof'
: error: ISO C++ forbids declaration of '_Static_assert' with no type [-fpermissive]
D : error: '_Static_assert' was not declared in this scope; did you mean 'static_assert'?
The last error made me think that the problem is with <assert.h> included somehow (through a long chain of includes). I found it and removed "#include <assert.h>", after that all errors are gone.
Questions:
Thank you!
Something in one of your headers appears to be doing #define static_assert _Static_assert
, which fails in C++ because _Static_assert
is a (reserved) identifier with no special meaning; in particular it doesn't perform a static assertion. I get the same errors in an example by manually adding #define static_assert _Static_assert
, and similar ones if I do #define static_assert foobar
.
This macro should be in <assert.h>
when compiling as C, but a properly written <assert.h>
should wrap it in #ifndef __cplusplus
so that it doesn't apply to C++ sources. So I suspect either:
Your system's <assert.h>
is broken
Your compiler is confused about what language it's compiling (unlikely because then namespace
etc would also be syntax errors)
Something else in your tangle of headers (or command-line compilation options) is being naughty and causing #undef __cplusplus
or something like that. If you've found the place where <assert.h>
is included, you could try and track down the issue with strategic insertions of
#ifndef __cplusplus
#error Aargh
#endif
Normally you shouldn't have to do anything. Properly written system headers will support C++ via appropriate #ifdef
s, and work correctly when included into C++ programs.
If you have a header from some third-party library that is written as C only and doesn't support C++, then you have some work to do to adapt it (or complain to its vendors). That's a project beyond the scope of this answer. Wrapping everything in extern "C"
is a start but only a start.