跨平台的ALIGN(x)宏? [英] Cross-platform ALIGN(x) macro?

查看:124
本文介绍了跨平台的ALIGN(x)宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我想使用对于GCC和VisualC ++编译器,同样的结构体定义。

> __ declspec(align(32))$ b $ struct MyStruct
{
// ...
};

在GCC中,通常会这样做:

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

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

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

因此能够透明地处理这两种情况,但在这里我必须复制对齐常量( 32 ),我想避免它。



GCC的一个替代方法是将<$ c $如 __ attribute __ =noreferrer>文档,如下所示:

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

因此,我可以使这种类型的语法成为可能:

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

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






更新::基于@ John的评论,这是另一个可以工作的版本(我没有编译它,但文档表明它是一个好主意)

  struct MyStruct_Unaligned 
{
// ...
};

TYPEDEF_ALIGNED(32,MyStruct_Unaligned,MyStruct);

//将扩展为以下之一:
//
// typedef __declspec(align(32))MyStruct_Unaligned MyStruct;
//
// typedef struct __attribute__((aligned(32)))MyStruct_Unaligned MyStruct


解决方案

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

$ $ p $ $ $ $ $ $ $ $# __declspec(align(x))
#else
#if defined(__ GNUC__)
#define ALIGNED_(x)__attribute__((aligned(x)))
#endif
#endif

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

/ *某些使用示例* /

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
{
/ *联盟成员到这里* /

} 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); (i = 0; i <4; i ++)
{
printf(Addrof%s:%x \ n,names [i],ptrs)的

[一世]);
printf(Sizeof%s:%d \\\
,名称[i],大小[i]);
for(j = 0; j printf(%s对齐%d个字节?%s \ n,
名称[i],
alignments [j],
((size_t)ptrs [i])%alignments [j] == 0?YES:NO);
}

for(j = 0; j {
printf(_alignedmember.alignedInt对齐%d个字节?%s \ n,
alignments [j],
((size_t)& _alignedmembers.alignedInt)%alignments [j] == 0?YES:NO);
printf(_alignedmember.alignedDouble%d字节对齐%s \ n,
alignments [j],
((size_t)& _alignedmembers.alignedDouble)%路线[ j] == 0?YES:NO);
printf(_alignedmember.alignedChar对齐%d个字节?%s \ n,
路线[j],
((size_t)& _alignedmembers.alignedChar)%路线[ j] == 0?YES:NO);
}

返回0;
}

希望这有助于...


I would like to create a struct that has a certain alignment.

I would like to use the same struct definition for both GCC and VisualC++ compilers.

In VisualC++, one typically does this:

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

In GCC, one typically does this:

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

I could of course create the appropriate macros to make this work:

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

And thus be able to handle both cases transparently, but here I have to duplicate the alignment constant (32), which I'd like to avoid.

An alternative in GCC is to put the __attribute__ after the struct tag, as mentioned in the docs, like so:

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

And thus I could make this type of syntax work:

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

Does anyone have any better versions? Other ideas? I tried a little code searching, but didn't find anything too promising.


Update: Based on @John's comment, here's another version that could work (I haven't compiled it, but the docs indicate it's an OK idea)

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

解决方案

I know this thread is quite old - however it is yet to be marked as answered and the solutions mentioned are not the easiest to use. The best way to solve this is to notice that MSVC allows the declspec to appear after the declarator. Here is my own implementation:

#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;

You can test this with the following code (notice the #pragma pack --> This is for 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;
}

Hope this helps...

这篇关于跨平台的ALIGN(x)宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆