GCC:_Static_assert“静态断言的非常量条件”

问题描述 投票:0回答:1

我有更大的 C 代码库,我想在其中集成一些 C++ 代码。 C++ 代码需要来自 C 代码库的一些声明。

编译器目前是 GCC 6.3.1,但我们也许可以更新编译器。

基本上,包含的 C 头文件包含如下代码:

#define NRF_GPIO  ((int*)          0x0000112233)
static_assert(NRF_GPIO == NRF_GPIO, "asd");

如果编译器编译 C 文件,这编译得很好,但如果代码是用 C++ 编写的,则编译失败,因为重新解释转换不会在常量表达式中产生,并且编译器正确地抱怨它:

error: non-constant condition for static assertion
 static_assert(NRF_GPIO == NRF_GPIO, "asd");
                        ^
t.cpp:2:20: error: reinterpret_cast from integer to pointer
 #define NRF_GPIO  ((int*)          0x0000112233)
                   ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.cpp:3:15: note: in expansion of macro 'NRF_GPIO'
 static_assert(NRF_GPIO == NRF_GPIO, "asd");

有没有办法让 GCC 更轻松地编译 C++,从而排除上面的代码?

c++ c gcc reinterpret-cast static-assert
1个回答
2
投票

也不保证在 C 中工作。在 C 中,静态断言需要一个 整数常量表达式,它可能仅作为

sizeof
_Alignof
操作数的一部分包含对非整数类型的强制转换。

C 确实允许实现允许其他形式的常量表达式,但至少在当前的 C23 工作草案中已经阐明这不会影响作为整数常量表达式的有效性。见N2713

GCC 也用

-pedantic
警告这一点。

您通常不能凭空发明指针值并在 C++ 的编译时使用它们(空指针值除外)。 C 允许稍微多一些,但在需要 integer constant expressions 的上下文中不允许。见下文。

解决这个问题的唯一方法是在编译时将地址保留为数值,并仅在运行时需要时将其转换为指针。

C 中有一个例外,但 C++ 中没有:整数常量可以转换为指针并用作 地址常量 以常量初始化变量。然而,即使这样,地址常量也不能作为初始化表达式中

==
(或大多数其他运算符)的操作数,也不允许在整数常量表达式中使用。

© www.soinside.com 2019 - 2024. All rights reserved.