gpt4 book ai didi

visual-c++ - 跨平台ALIGN(x)宏?

转载 作者:行者123 更新时间:2023-12-03 13:52:01 25 4
gpt4 key购买 nike

我想创建一个具有一定对齐方式的struct

我想对GCC和VisualC ++编译器使用相同的结构定义。

在VisualC ++中,通常会执行以下操作:

__declspec(align(32))
struct MyStruct
{
// ...
};


在GCC中,通常这样做:

struct MyStruct
{
// ...
} __attribute__ ((aligned (32)));


我当然可以创建适当的宏来完成这项工作:

BEGIN_ALIGNED_STRUCT(32)
struct
{
// ...
}
END_ALIGNED_STRUCT(32)
;


这样就可以透明地处理这两种情况,但是在这里我必须复制对齐常数( 32),我想避免这种情况。

在GCC中的另一种方法是将 __attribute__放在struct标记之后,如 the docs中所述,如下所示:

struct __attribute__ ((aligned (32))) MyStruct
{
// ...
};


因此,我可以使这种类型的语法起作用:

ALIGNED_STRUCT(32) MyStruct
{
// ...
};


有人有更好的版本吗?还有其他想法吗?
我尝试了一些代码搜索,但没有发现任何有前途的东西。



更新:根据@John的评论,这是另一个可行的版本(我尚未对其进行编译,但是文档表明这是一个好主意)

struct MyStruct_Unaligned
{
// ...
};

TYPEDEF_ALIGNED(32, MyStruct_Unaligned, MyStruct);

// Would expand to one of:
//
// typedef __declspec(align(32)) MyStruct_Unaligned MyStruct;
//
// typedef struct __attribute__ ((aligned (32))) MyStruct_Unaligned MyStruct

最佳答案

我知道这个线程已经很老了-但是它尚未被标记为已回答,并且提到的解决方案并不是最容易使用的。
解决此问题的最佳方法是注意MSVC允许declspec出现在声明程序之后。
这是我自己的实现:

#if defined(_MSC_VER)
#define ALIGNED_(x) __declspec(align(x))
#else
#if defined(__GNUC__)
#define ALIGNED_(x) __attribute__ ((aligned(x)))
#endif
#endif

#define _ALIGNED_TYPE(t,x) typedef t ALIGNED_(x)

/*SOME USAGE SAMPLES*/

ALIGNED_TYPE_(double, 16) aligned_double_t;

ALIGNED_TYPE_(struct, CACHE_LINE) tagALIGNEDSTRUCT
{
/*STRUCT MEMBERS GO HERE*/
}aligned_struct_t;

ALIGNED_TYPE_(union, CACHE_LINE) tagALIGNEDUNION
{
/*UNION MEMBERS GO HERE*/

}aligned_union_t;


您可以使用以下代码进行测试(请注意#pragma pack->这是针对MSVC的)

#if defined(_MSC_VER)
#define ALIGNED_(x) __declspec(align(x))
#else
#if defined(__GNUC__)
#define ALIGNED_(x) __attribute__ ((aligned(x)))
#endif
#endif

#define ALIGNED_TYPE_(t,x) typedef t ALIGNED_(x)

#pragma pack(1)
typedef struct tagSTRUCTPACKED
{
int alignedInt;
double alignedDouble;
char alignedChar;
}struct_packed_t;
#pragma pack()

typedef struct tagSTRUCTNOALIGN
{
int alignedInt;
double alignedDouble;
char alignedChar;
}struct_no_align_t;

typedef struct ALIGNED_(64) tagSTRUCTALIGNED64
{
int alignedInt;
double alignedDouble;
char alignedChar;
}struct_aligned_64_t;


typedef struct tagSTRUCTWITHALIGNEDMEMBERS
{
int ALIGNED_(8) alignedInt;
double ALIGNED_(16) alignedDouble;
char ALIGNED_(2) alignedChar;
}struct_with_aligned_members_t;

int main(int argc, char **argv)
{
int i,j;
struct_packed_t _packed;
struct_no_align_t _noalign;
struct_aligned_64_t _aligned64;
struct_with_aligned_members_t _alignedmembers;

char* names[] = {"_packed","_noalign","_aligned64","_alignedmembers"};
char* ptrs[] = {(char*)&_packed,(char*)&_noalign,(char*)&_aligned64,(char*)&_alignedmembers};
size_t sizes[] = {sizeof(_packed),sizeof(_noalign),sizeof(_aligned64),sizeof(_alignedmembers)};
size_t alignments[] = {2,4,8,16,32,64};
int alcount = sizeof(alignments)/sizeof(size_t);

for(i = 0; i < 4; i++)
{
printf("Addrof %s: %x\n", names[i], ptrs[i]);
printf("Sizeof %s: %d\n", names[i], sizes[i]);
for(j = 0; j < alcount; j++)
printf("Is %s aligned on %d bytes? %s\n",
names[i],
alignments[j],
((size_t)ptrs[i])%alignments[j] == 0 ? "YES" : "NO");
}

for(j = 0; j < alcount; j++)
{
printf("Is _alignedmember.alignedInt aligned on %d bytes? %s\n",
alignments[j],
((size_t)&_alignedmembers.alignedInt)%alignments[j] == 0 ? "YES" : "NO");
printf("Is _alignedmember.alignedDouble aligned on %d bytes? %s\n",
alignments[j],
((size_t)&_alignedmembers.alignedDouble)%alignments[j] == 0 ? "YES" : "NO");
printf("Is _alignedmember.alignedChar aligned on %d bytes? %s\n",
alignments[j],
((size_t)&_alignedmembers.alignedChar)%alignments[j] == 0 ? "YES" : "NO");
}

return 0;
}


希望这可以帮助...

关于visual-c++ - 跨平台ALIGN(x)宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7895869/

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