我正在优化一种压缩算法,该算法使用跨 2 个字节的结构。但有时我希望它只解释 1 个字节,因为(我希望)映射到第二个字节的成员永远不会被写入或读取。
我是否能保证只要
zFmt
和 wFmt
从未被访问过,编译器就不会访问第二个字节?如果不是,我可以编写一个静态断言,当这个假设错误时将停止编译吗?
struct Header {
uint8_t xFmt : 4;
uint8_t yFmt : 4;
uint8_t zFmt : 4; // must not be read/written when header is mapped to 1 byte
uint8_t wFmt : 4; // must not be read/written when header is mapped to 1 byte
};
static_assert( sizeof(Header) == 2 && alignof(Header) == 1, "alignment vital");
// --- usage ---
int main(){
// Header may be placed into memory where it overlaps only one byte;
// in that case, it's .zFmt and .wFmt members are never read or written to
char buffer[1];
Header * header = new (buffer) Header;
// can I be sure (or statically assert) that these instructions
// will only read and write to the nearest (and only) owned byte?
header->xFmt = 0;
header->yFmt = 0;
header->xFmt += 1;
header->yFmt += 1;
}
旁注:
该算法目前有效,但我想确保它不依赖于未定义的行为。我相信通过使用新的放置来遵守严格别名,但也许这个假设是不正确的?
另外,我想以这种方式使用这个结构和位域......因为它们看起来不错!这不是最好的原因哈哈,所以如果这是不可能的,我的后备方法是将没有结构的字节解释为带有移位和掩码的 uint8_t 。我还知道我可以使用继承来执行切片,如果这是未定义的,我将研究它。