gpt4 book ai didi

c++ - 用位域打包 bools (C++)

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:44:54 25 4
gpt4 key购买 nike

我正在尝试使用 C++ 与 Ada 代码进行交互,因此我正在使用位字段定义一个结构,以便所有数据在两种语言中都位于同一位置。以下内容不完全是我在做什么,但概述了问题。以下也是 VS2008 中的控制台应用程序,但这不是特别相关。

using namespace System;
int main() {
int array1[2] = {0, 0};
int *array2 = new int[2]();
array2[0] = 0;
array2[1] = 0;

#pragma pack(1)
struct testStruct {
// Word 0 (desired)
unsigned a : 8;
unsigned b : 1;
bool c : 1;
unsigned d : 21;
bool e : 1;

// Word 1 (desired)
int f : 32;

// Words 2-3 (desired)
int g[2]; //Cannot assign bit field but takes 64 bits in my compiler
};
testStruct test;

Console::WriteLine("size of char: {0:D}", sizeof(char) * 8);
Console::WriteLine("size of short: {0:D}", sizeof(short) * 8);
Console::WriteLine("size of int: {0:D}", sizeof(int) * 8);
Console::WriteLine("size of unsigned: {0:D}", sizeof(unsigned) * 8);
Console::WriteLine("size of long: {0:D}", sizeof(long) * 8);
Console::WriteLine("size of long long: {0:D}", sizeof(long long) * 8);
Console::WriteLine("size of bool: {0:D}", sizeof(bool) * 8);
Console::WriteLine("size of int[2]: {0:D}", sizeof(array1) * 8);
Console::WriteLine("size of int*: {0:D}", sizeof(array2) * 8);
Console::WriteLine("size of testStruct: {0:D}", sizeof(testStruct) * 8);
Console::WriteLine("size of test: {0:D}", sizeof(test) * 8);

Console::ReadKey(true);

delete[] array2;
return 0;
}

(如果不清楚,在实际程序中,基本思想是程序从与 Ada 代码通信的东西中获取 void* 并将其转换为 testStruct * 访问数据。)

注释掉#pragma pack(1)后,输出为:

size of char: 8
size of short: 16
size of int: 32
size of unsigned: 32
size of long: 32
size of long long: 64
size of bool: 8
size of int[2]: 64
size of int*: 32
size of testStruct: 224
size of test: 224

显然 4 个字(索引为 0-3)应该是 448 = 32*4 = 128 位,而不是 224。其他输出行用于帮助确认 VS2008 下类型的大小编译器。

#pragma pack(1) 未注释的情况下,该数字(在输出的最后两行)减少到 176,它仍然大于 128。它似乎 bool 值没有与“Word 0”中的无符号整数打包在一起。

注意:a&b、c、d、e、f,用不同的词打包就是5,数组+2=7个词,乘以32位=224,我们得到的数字#pragma pack(1) 注释掉了。如果 c 和 e( bool 值)各占 8 位,而不是 32 位,我们得到 176,这是我们用 #pragma pack(1) 得到的数字> 未评论。似乎 #pragma pack(1) 只允许 bools 自己打包成单个字节,而不是单词,但根本不允许带有无符号整数的 bools。

所以我的问题,一句话:有没有办法强制编译器将 a 到 e 打包成一个词?相关的是这个问题:C++ bitfield packing with bools ,但这并没有回答我的问题;它只会指出我试图强制消失的行为。

如果真的没有办法做到这一点,有没有人有任何解决方法的想法?我很茫然,因为:

  1. 我被要求避免更改我正在复制的结构格式(不重新排序)。
  2. 我不想将 bool 更改为 unsigned int,因为它可能会导致问题不断地重新转换为 bool 并且可能不小心使用了重载函数的错误版本,更不用说制作代码对后来阅读它的其他人来说更晦涩。
  3. 我不想将它们声明为私有(private)无符号整数然后创建公共(public)访问器或其他东西,因为项目中所有其他结构的所有其他成员都可以直接访问而无需 () 之后,所以它会看起来有点古怪和迟钝,几乎需要 IntelliSense 或反复试验才能记住哪些需要 () 哪些不需要。
  4. 我想避免仅为数据转换创建另一个结构类型(例如,为 testStruct 创建一个构造函数,它接受一个 testStructImport 类型的对象)因为实际结构很长,有很多位域指定的变量。

最佳答案

我建议您创建一个没有任何位压缩的“正常”结构。为成员使用默认的 POD 类型。

创建接口(interface)函数,用于从缓冲区 (uint8_t) 加载“正常”字段,并存储到缓冲区。

这将允许您在程序中以合理的方法使用数据成员。位打包和解包将由接口(interface)函数处理。 bit twiddling 应该使用按位 AND 和按位 OR 函数,而不是依赖于结构中的位域符号。这将允许您调整位旋转并在编译器之间更具可移植性。

这就是我设计协议(protocol)类的方式。而且我不必担心位域定位、Endianess 或类似的事情。

另外,我可以使用 block I/O 来读取和写入缓冲区。

关于c++ - 用位域打包 bools (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24765685/

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