문제
나는 각 비트가 정확 해야하는 소프트웨어를 작성하고 있습니다 (CPU의 경우) __packed가 매우 중요합니다.
typedef union{
uint32_t raw;
struct{
unsigned int present:1;
unsigned int rw:1;
unsigned int user:1;
unsigned int dirty:1;
unsigned int free:7;
unsigned int frame:20;
} __packed;
}__packed page_union_t;
그것이 나의 구조와 연합입니다. 그러나 작동하지 않습니다.
page_union_t p; //.....
//This:
p.frame=trg_page;
p.user=user;
p.rw=rw;
p.present=present;
//and this:
p.raw=trg_page<<12 | user<<2 | rw<<1 | present;
동일한 UINT32를 생성해야합니다. 그러나 그들은 같은 것을 만들지 않습니다.
내 노조에 잘못된 것을 볼 수없는 것이 있습니까?
해결책
구조물에는 31 비트 만 있습니다
다른 팁
구조물의 비트가 저장되는 순서는 C99 표준 (및 C89 표준)에 의해 정의되지 않은 Afaik. 아마도 비트는 예상했던 것과 반대 순서입니다.
당신은 당신이 얻은 결과와 당신이 기대 한 결과를 보여 주었을 것입니다 - 그것은 진단에 도움이 될 것입니다. 사용하는 컴파일러와 실행하는 플랫폼도 중요 할 수 있습니다.
MacOS x 10.4.11 (PowerPC G4) 에서이 코드 :
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint32_t raw;
struct
{
unsigned int present:1;
unsigned int rw:1;
unsigned int user:1;
unsigned int dirty:1;
unsigned int free:7;
unsigned int frame:20;
};
} page_union_t;
int main(void)
{
page_union_t p = { .raw = 0 }; //.....
unsigned trg_page = 0xA5A5A;
unsigned user = 1;
unsigned rw = 1;
unsigned present = 1;
p.frame = trg_page;
p.user = user;
p.rw = rw;
p.present = present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw <<= 1;
printf("p.raw = 0x%08X\n", p.raw);
return(0);
}
표시된 결과를 생성합니다.
p.raw = 0xE014B4B4
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E
필드의 순서가 역전되면 결과는 거의 더 설명 할 수 있습니다.
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint32_t raw;
struct
{
unsigned int frame:20;
unsigned int free:7;
unsigned int dirty:1;
unsigned int user:1;
unsigned int rw:1;
unsigned int present:1;
};
} page_union_t;
int main(void)
{
page_union_t p = { .raw = 0 }; //.....
unsigned trg_page = 0xA5A5A;
unsigned user = 1;
unsigned rw = 1;
unsigned present = 1;
p.frame = trg_page;
p.user = user;
p.rw = rw;
p.present = present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw <<= 1;
printf("p.raw = 0x%08X\n", p.raw);
return(0);
}
결과를 제공합니다.
p.raw = 0xA5A5A00E
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E
비트 필드 구조에 31 비트가 정의되어 있기 때문에 첫 번째 결과는 최소한의 유의 한 비트가 사용되지 않기 때문에 E를 마지막 16 진수로 사용합니다.
비트의 정확한 위치가 중요하다면, 가장 안전한 베팅은 명백한 포장 및 구조를 서명되지 않은 Char 어레이로 풀고 풀리는 것입니다. 다른 모든 것은 너무 구현에 따라 다릅니다.
이것을 찾을 수있는 사람과 관련하여 포장 된 속성을 시도하십시오.
struct __attribute__((packed)){
}
당신은 당신이 사전에 구조물의 비트를 제거하고 있다고 언급하지 않습니다. 첫 번째 경우에는 쓰레기 비트가 남아 있지 않습니까?
// maybe try this
page_union_t p = {0};