Nic*_*yer 10 c++ struct bit-manipulation padding
我正在为嵌入式系统开发一些C++代码.代码使用的I/O接口要求每条消息的大小(以字节为单位)是2的幂.现在,代码执行类似的操作(在几个地方):
#pragma pack(1)
struct Message
{
struct internal_
{
unsigned long member1;
unsigned long member2;
unsigned long member3;
/* more members */
} internal;
char pad[64-sizeof(internal_)];
};
#pragma pack()
Run Code Online (Sandbox Code Playgroud)
我正在尝试首次在64位Fedora上编译代码,其中long
64位.在这种情况下,sizeof(internal_)
大于64,数组大小表达式下溢,并且编译器抱怨数组太大.
理想情况下,我希望能够编写一个宏来获取结构的大小,并在编译时评估填充数组所需的大小,以便将结构的大小舍入为2的幂.
我看过Bit Twiddling Hacks页面,但我不知道是否有任何技术可以在宏中实现,以便在编译时进行评估.
这个问题的任何其他解决方案?或者我应该延续这个问题,只需将神奇的64改为神奇的128?
fiz*_*zer 15
使用模板元程序.(编辑回应评论).
#include <iostream>
#include <ostream>
using namespace std;
template <int N>
struct P
{
enum { val = P<N/2>::val * 2 };
};
template <>
struct P<0>
{
enum { val = 1 };
};
template <class T>
struct PadSize
{
enum { val = P<sizeof (T) - 1>::val - sizeof (T) };
};
template <class T, int N>
struct PossiblyPadded
{
T payload;
char pad[N];
};
template <class T>
struct PossiblyPadded<T, 0>
{
T payload;
};
template <class T>
struct Holder : public PossiblyPadded<T, PadSize<T>::val>
{
};
int main()
{
typedef char Arr[6];
Holder<Arr> holder;
cout << sizeof holder.payload << endl;
// Next line fails to compile if sizeof (Arr) is a power of 2
// but holder.payload always exists
cout << sizeof holder.pad << endl;
}
Run Code Online (Sandbox Code Playgroud)
可能最明显的方法是使用三元运算符:
#define LOG2_CONST(n) ((n) <= 1 ? 0 :
((n) <= 2 ? 1 :
((n) <= 4 ? 2 :
/* ... */
))))))))))))))))))))))))))))))
#define PADDED_STRUCT(ResultName, BaseName) \
typedef union { BaseName data; char pad[1 << LOG2_CONST(sizeof(BaseName))]; } ResultName
Run Code Online (Sandbox Code Playgroud)
为什么不使用工会?
union Message
{
struct internal_
{
unsigned long member1;
/* more members */
};
char[64];
};
Run Code Online (Sandbox Code Playgroud)
或者更好地使用匿名结构
union Message
{
struct
{
unsigned long member1;
/* more members */
};
char[64];
};
Run Code Online (Sandbox Code Playgroud)
所以你可以访问这样的成员:Message.member1;
编辑:显然这不能解决你的大于64的问题,但提供了一种更简洁的填充方式.
归档时间: |
|
查看次数: |
3591 次 |
最近记录: |