簡體   English   中英

指向結構的指針可以別名為無符號char數組嗎?

[英]Can a pointer to struct alias an unsigned char array?

#include "stdio.h"  


/* array to store data receeived from CAN Bus */
unsigned char a[8] = {0xCD, 0xEF, 0x12, 0x34, 0x50, 0x00, 0x00, 0x00};

typedef struct {
    unsigned int a:12;
    unsigned int b:12;
    unsigned int c:12;
    unsigned int unused:28;
}test;

test *tptr;

int main(void)
{

    tptr = (test*)( (void*)&a); // is this line braking any aliasing rule

    if(tptr->a == 0xCDE)
    {
        printf("\n data received ok");

    }

    return 0;
}

我最近了解了C語言中由於指針別名引起的問題。我想知道上面的代碼是否違反了任何規則。 會導致問題嗎?

我知道位域的順序取決於機器和實現。 但是,我的問題是關於指針別名規則,我想更清楚地了解它。

它確實破壞了嚴格的別名。 一些(更tptr )編譯器確實推斷出顯然應該允許tptra別名,但這不是標准所保證的。 事實上,GCC不會考慮tptr被混疊a

另一個問題是的對准a 在這方面,x86的容忍度很高,但包括ARM在內的許多其他體系結構卻沒有。

考慮在僅支持從本身是sizeof(int)倍數的地址中獲取int的體系結構上的(int)&a == 0xFFF02sizeof(int) == 4 如果您進行*(int*)&a甚至更糟的是程序訪問錯誤的位置,則這種未對齊的訪問將導致總線錯誤。

為了避免出現未定義的行為,請記住要確保通過unsigned char*進行的訪問無需對齊或混疊約束,而不是相反。 因此使用:

test buf;
can_recv((unsigned char*)&buf, sizeof buf);
if(tptr->a == 0xCDE)
{
    printf("\n data received ok");

}

另一個可移植性問題是您希望以某種方式打包位域。 但是標准並不能保證 如果您想要可移植的行為,請將自己限制在bitfield接口( bitfield.b1 = 1 )上,不要通過其他方式修改bitfied。

如果不考慮可移植性,請確保設置適當的編譯器標志,以保證您期望的位域打包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM