结构中的位是否保证是连续的?
are bits in structs guaranteed to be contiguous?
我玩过 https://gcc.godbolt.org/,这段代码似乎总是 return 1.
但是我想知道标准是否保证这一点。
#include <cstdint>
struct S{
uint8_t a : 6;
uint8_t b : 2;
};
int main(){
return sizeof(S);
}
我的真实例子如下:
struct Pair{
uint64_t created; // 8 bytes
uint32_t expires; // 4 bytes
uint16_t keylen; // 2 bytes, 4 bits are used for vallen. 2 bits are reserved for future versions. 10 bytes for keylen.
uint16_t vallen; // 2 bytes
};
目前我在做一些位掩码和移位。
我可以这样做吗?它会一直工作吗(任何“普通”编译器)?
keylen
在 Big Endian 上的表现如何?使用移位我总是使用前 4 位。
struct Pair{
uint64_t created;
uint32_t expires;
uint8_t vallen2 : 4;
uint8_t future : 2;
uint16_t keylen : 10;
uint16_t vallen;
};
大多数编译器会为您提供打包在一起的位字段,尽管行为是实现定义的。
一种检查方法是添加 static_assert
来比较有无位域的结构定义的大小。这样,一旦实现没有按照您的预期进行,您将得到一个不错的编译时错误。
#include <cstdint>
struct Pair_size_check{
uint64_t created; // 8 bytes
uint32_t expires; // 4 bytes
uint16_t keylen; // 2 bytes, 4 bits are used for vallen. 2 bits are reserved for future versions. 10 bytes for keylen.
uint16_t vallen; // 2 bytes
};
struct Pair{
uint64_t created;
uint32_t expires;
uint8_t vallen2 : 4;
uint8_t future : 2;
uint16_t keylen : 10;
uint16_t vallen;
};
static_assert(sizeof(Pair) == sizeof(Pair_size_check));
我玩过 https://gcc.godbolt.org/,这段代码似乎总是 return 1.
但是我想知道标准是否保证这一点。
#include <cstdint>
struct S{
uint8_t a : 6;
uint8_t b : 2;
};
int main(){
return sizeof(S);
}
我的真实例子如下:
struct Pair{
uint64_t created; // 8 bytes
uint32_t expires; // 4 bytes
uint16_t keylen; // 2 bytes, 4 bits are used for vallen. 2 bits are reserved for future versions. 10 bytes for keylen.
uint16_t vallen; // 2 bytes
};
目前我在做一些位掩码和移位。
我可以这样做吗?它会一直工作吗(任何“普通”编译器)?
keylen
在 Big Endian 上的表现如何?使用移位我总是使用前 4 位。
struct Pair{
uint64_t created;
uint32_t expires;
uint8_t vallen2 : 4;
uint8_t future : 2;
uint16_t keylen : 10;
uint16_t vallen;
};
大多数编译器会为您提供打包在一起的位字段,尽管行为是实现定义的。
一种检查方法是添加 static_assert
来比较有无位域的结构定义的大小。这样,一旦实现没有按照您的预期进行,您将得到一个不错的编译时错误。
#include <cstdint>
struct Pair_size_check{
uint64_t created; // 8 bytes
uint32_t expires; // 4 bytes
uint16_t keylen; // 2 bytes, 4 bits are used for vallen. 2 bits are reserved for future versions. 10 bytes for keylen.
uint16_t vallen; // 2 bytes
};
struct Pair{
uint64_t created;
uint32_t expires;
uint8_t vallen2 : 4;
uint8_t future : 2;
uint16_t keylen : 10;
uint16_t vallen;
};
static_assert(sizeof(Pair) == sizeof(Pair_size_check));