static_assert C++ 与 C 中的用法
static_assert usage in C++ vs C
这是一个庞大项目的一部分,所以我 post 从一个 cc 文件中摘录(实际代码中只需要一个 static_assert,我只是试验了一下):
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 报如下错误(A、B、C、D 分别对应):
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'?
最后一个错误让我认为问题出在 以某种方式包含(通过一长串包含)。我找到它并删除了“#include ”,之后所有错误都消失了。
问题:
- 案例 A、B、C 中的错误是什么意思?
- 最重要的:一般情况下如何处理混合C和C++文件?
如果我无法删除(甚至找不到)相应的
怎么办?我如何告诉编译器使用 C++ 版本的 static_assert,而不是 C 宏?
谢谢!
- Most important: how to handle in general situation with mixing C and C++ files?
您可以 link 使用 C++ 编译器编译的 C++ 翻译单元和使用 C 编译器编译的 C 翻译单元。您可以使用语言的通用子集编写头文件。您可以在必要时使用宏来改变声明 - 最常见的是在包含在 C++ 中时将 C linkage 说明符添加到声明中。
How can I tell compiler to use C++ version of static_assert, not C macro?
使用符合标准的C++语言实现,没有问题。这是您在 GCC 9 中运行的示例程序:https://godbolt.org/z/hEsMT8W93
你的一个 header 中的某些东西似乎在做 #define static_assert _Static_assert
,这在 C++ 中失败了,因为 _Static_assert
是一个(保留的)标识符,没有特殊的意义;特别是它不执行静态断言。我通过手动添加 #define static_assert _Static_assert
在 an example 中得到相同的错误,如果我这样做 #define static_assert foobar
.
也会得到类似的错误
当编译为 C 时,这个宏应该在 <assert.h>
中,但是正确编写的 <assert.h>
应该将它包装在 #ifndef __cplusplus
中,这样它就不适用于 C++ 源代码。所以我怀疑:
你的系统 <assert.h>
坏了
您的编译器对它正在编译的语言感到困惑(不太可能因为 namespace
等也将是语法错误)
在你的 headers(或 command-line 编译选项)的纠结中还有一些东西很顽皮,导致 #undef __cplusplus
或类似的东西。如果您找到包含 <assert.h>
的地方,您可以尝试通过战略性插入
来追踪问题
#ifndef __cplusplus
#error Aargh
#endif
通常你不需要做任何事情。正确编写的系统 headers 将通过适当的 #ifdef
s 支持 C++,并在包含到 C++ 程序中时正常工作。
如果您有来自某个 third-party 库的 header 仅以 C 语言编写且不支持 C++,那么您需要做一些工作来适应它(或抱怨它供应商)。这是一个超出此答案范围的项目。将所有内容包装在 extern "C"
中是一个开始,但只是一个开始。
这是一个庞大项目的一部分,所以我 post 从一个 cc 文件中摘录(实际代码中只需要一个 static_assert,我只是试验了一下):
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 报如下错误(A、B、C、D 分别对应):
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'?
最后一个错误让我认为问题出在
问题:
- 案例 A、B、C 中的错误是什么意思?
- 最重要的:一般情况下如何处理混合C和C++文件?
如果我无法删除(甚至找不到)相应的
怎么办?我如何告诉编译器使用 C++ 版本的 static_assert,而不是 C 宏?
谢谢!
- Most important: how to handle in general situation with mixing C and C++ files?
您可以 link 使用 C++ 编译器编译的 C++ 翻译单元和使用 C 编译器编译的 C 翻译单元。您可以使用语言的通用子集编写头文件。您可以在必要时使用宏来改变声明 - 最常见的是在包含在 C++ 中时将 C linkage 说明符添加到声明中。
How can I tell compiler to use C++ version of static_assert, not C macro?
使用符合标准的C++语言实现,没有问题。这是您在 GCC 9 中运行的示例程序:https://godbolt.org/z/hEsMT8W93
你的一个 header 中的某些东西似乎在做
也会得到类似的错误#define static_assert _Static_assert
,这在 C++ 中失败了,因为_Static_assert
是一个(保留的)标识符,没有特殊的意义;特别是它不执行静态断言。我通过手动添加#define static_assert _Static_assert
在 an example 中得到相同的错误,如果我这样做#define static_assert foobar
.当编译为 C 时,这个宏应该在
<assert.h>
中,但是正确编写的<assert.h>
应该将它包装在#ifndef __cplusplus
中,这样它就不适用于 C++ 源代码。所以我怀疑:你的系统
<assert.h>
坏了您的编译器对它正在编译的语言感到困惑(不太可能因为
namespace
等也将是语法错误)在你的 headers(或 command-line 编译选项)的纠结中还有一些东西很顽皮,导致
来追踪问题#undef __cplusplus
或类似的东西。如果您找到包含<assert.h>
的地方,您可以尝试通过战略性插入
#ifndef __cplusplus
#error Aargh
#endif
通常你不需要做任何事情。正确编写的系统 headers 将通过适当的
#ifdef
s 支持 C++,并在包含到 C++ 程序中时正常工作。如果您有来自某个 third-party 库的 header 仅以 C 语言编写且不支持 C++,那么您需要做一些工作来适应它(或抱怨它供应商)。这是一个超出此答案范围的项目。将所有内容包装在
extern "C"
中是一个开始,但只是一个开始。