gpt4 book ai didi

c - 是否可以在 GCC/GNU C 中编写一个 _Static_assert 来验证编译时内存中位字段的布局?

转载 作者:行者123 更新时间:2023-12-03 16:55:41 31 4
gpt4 key购买 nike

假设我有以下定义:

#include <stdbool.h>
#include <stdint.h>
#define ASSERT(cond) _Static_assert(cond, #cond)

typedef union {
struct {
bool bit0:1;
bool bit1:1;
bool bit2:1;
bool bit3:1;
bool bit4:1;
bool bit5:1;
bool bit6:1;
bool bit7:1;
};
uint8_t bits;
} byte;

ASSERT(sizeof(byte) == sizeof(uint8_t));

能不能写个代码,比如
#include <assert.h>
// ...
assert(((byte) { .bit0 = 1 }).bits == 0b00000001);
assert(((byte) { .bit1 = 1 }).bits == 0b00000010);
assert(((byte) { .bit2 = 1 }).bits == 0b00000100);
assert(((byte) { .bit3 = 1 }).bits == 0b00001000);
assert(((byte) { .bit4 = 1 }).bits == 0b00010000);
assert(((byte) { .bit5 = 1 }).bits == 0b00100000);
assert(((byte) { .bit6 = 1 }).bits == 0b01000000);
assert(((byte) { .bit7 = 1 }).bits == 0b10000000);
// ...

如果不满足上述条件,那会导致编译时失败吗?

(当我尝试在 ASSERT 宏中放置条件时,编译器提示 expression in static assertion is not constant ,这当然很有意义)

该解决方案允许使用 C 语言的 GNU 扩展。

最佳答案

我不认为你可以。_Static_assert需要验证参数表达式是否满足标准 C 对整数常量表达式的要求。

有一些方法在 gcc 上有时可以将不满足这​​些要求但在编译时为优化器已知的 bool 表达式转换为编译时错误或警告。

例如:

#include <assert.h>
#if __GNUC__ && !__clang__
#define $SassertIfUCan0(X) \
(__extension__({ /*ellicit a -Wvla-larger-than */ \
(!__builtin_constant_p(X)) ? 0 : \
({ char volatile $SassertIfUCan0_[ (!__builtin_constant_p(X)||(X)) ? 1:-1]; \
$SassertIfUCan0_[0]=0,0;}); \
__auto_type $SassertIfUCan0 = X; \
assert($SassertIfUCan0); \
0; \
}))
#endif

int main(int C, char **V)
{
int x = 0; $SassertIfUCan0(x);
//these also ellicit compile-time errrors:
/*$SassertIfUCan0(C-C);*/
/*$SassertIfUCan0(C*0);*/
}

可以将编译时已知变量设为 null x ,这在技术上不是整数常量,变成编译/时间警告/错误
( "-Wvla-larger-than" )。

不幸的是,该宏不适用于每个表达式,其中包括基于位域的示例。

(如果表达式恰好在编译时已知且为假,我希望编译器有一种编译失败的机制。)

因此,AFAIK,您可以做的最接近的事情是编译时检测平台,其 ABI 已知可以保证您所需的位域布局:
#if __linux__ && __x86_64__
#elif 0//...
//...
#else
#error "bitfields not known to be little-endian"
#endif

关于c - 是否可以在 GCC/GNU C 中编写一个 _Static_assert 来验证编译时内存中位字段的布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61930322/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com