【发布时间】:2021-04-01 20:17:22
【问题描述】:
我正在尝试将 static_assert 用于 FPGA 的寄存器,并定义了以下带有位域和所有变量的结构联合。但是每当我尝试编译时, static_assert 都不会编译,并且我收到一条错误消息,指出变量没有命名类型。如果我尝试转发声明,它并不能解决问题。我不确定让 static_assert 工作的正确模式是什么。对编写以下代码的正确方法有任何想法吗?
so.h:
#include <stdint.h>
#define t_f2bits_addr (0x0000)
typedef union {
struct {
uint32_t do_it : 1;
uint32_t fault : 1;
} field;
uint32_t all;
} t_f2bits_type;
#define t_f2bits_ptr (*(volatile t_f2bits_type *)t_f2bits_addr)
t_f2bits_type myVar;
myVar.field.do_it = 0x1;
myVar.field.fault = 0x1;
static_assert(myVar.all == 0x3, "Not equal");
so.c
#include "so.h"
int main()
{
return 0;
}
运行:
g++ so.c
In file included from so.c:1:0:
so.h:15:1: error: ‘myVar’ does not name a type
myVar.field.do_it = 0x1;
^~~~~
so.h:16:1: error: ‘myVar’ does not name a type
myVar.field.fault = 0x1;
^~~~~
so.h:17:1: error: non-constant condition for static assertion
static_assert(myVar.all == 0x3, "Not equal");
^~~~~~~~~~~~~
so.h:17:1: error: the value of ‘myVar’ is not usable in a constant expression
so.h:14:15: note: ‘myVar’ was not declared ‘constexpr’
t_f2bits_type myVar;
^~~~~
【问题讨论】:
-
请注意,您的代码在 C++ 中是非法的。 C++ 不允许通过联合进行类型双关语,除非它要访问联合内的标准布局类共享的公共初始成员序列。
-
您不能在全局范围内编写代码。把它放在一个函数中(或
main)。然后你会发现你不能以这种方式使用static_assert。它只执行编译时检查。加上@NathanOliver 所说的话。 -
尽管在 C/C++ 中通过联合进行类型双关是非法的,但每个人都这样做:)
-
我绝对不是打算颠覆 C++ 语言哈哈……但是有没有一种模式可以让我使用 assert(最好是 static_assert)来测试位域的功能?
标签: c++ typedef unions bit-fields static-assert