2016-04-08 15 views
2

私は自分自身にビットフィールドを宣言したが(U8がunsinged整数8を意味)Cスカラー型をスカラーではなく後方にキャストするにはどうすればよいですか?

typedef struct build_field{ 

    u8 build : 5; 
    u8 ability : 1; 
    u8 hability : 1; 
    u8 shinyness : 1; 

} build_field; 

今、私はビットフィールドとして使用することができますので、関数によって返さ入ってくるU8値をキャストします。

build_field f = (build_field) func_that_returns_u8(); 

また、私はそれをu8値にキャストしたいと思います。

u8 x = (u8) field; 

しかし、私のCコンパイラはその操作を何もしません。どのように問題を解決するか?

+0

'U8ヴァル= 0xb5。 build = val & 0x1f;能力=(val&0x20)>> 5; hability =(val&0x40)>> 6; shinyness =(val&0x80)>> 7;またはビットを入れたい序列。 – pmg

答えて

4

利用組合:

union myunion 
{ 
    u8 value; 
    build_field field; 
}; 

union myunion m; 
m.value = func_that_returns_u8(); 
u8 a = m.ability; 

そうでない場合、これは動作しません構造体build_field内のメンバー間でのパディングがないことを確認してください。

より賢明な選択肢は、整数からビットを抽出することです。値のビットが構造体のメンバーと同じ順序であるとしましょう。 abilityhabilityの値を取得し、するには、実行します。

u8 value = func_that_returns_u8(); 
build_field f = { 0 }; 
f.hability = ((unsigned int)value >> 6U) & 1U; 
f.ability = ((unsigned int)value >> 5U) & 1U; 
0

あなたはこれをインライン化することができ、staticとC.組み合わせで全体の構造体を返すことができ、あまりにも

static build_field compose_field(unsigned char uc) 
{ 
union { 
     unsigned char uc; 
     build_field bf; 
     } uni = {uc}; 
return uni.bf; 
} 
(GCCで-O1から始まります)

使用

int main(void) 
{ 
build_field val; 

val = compose_field(0xa5); // "constructor" 
printf(" {%u %u %u %u}\n" 
     , (unsigned int) val.build 
     , (unsigned int) val.ability 
     , (unsigned int) val.hability 
     , (unsigned int) val.shinyness 
     ); 
return 0; 
} 

-O2と

GCC出力:非定数引数で

main: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp 
    subl $32, %esp 
    movl $1, 20(%esp) 
    movl $0, 16(%esp) 
    movl $1, 12(%esp) 
    movl $5, 8(%esp) 
    movl $.LC0, 4(%esp) 
    movl $1, (%esp) 
    call __printf_chk 
    xorl %eax, %eax 
    leave 
    ret 

:(uc = 0xa5 * random();):

main: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp 
    subl $32, %esp 
    call random 
    movl $-91, %ecx 
    xorl %edx, %edx 
    movl $.LC0, 4(%esp) 
    movl $1, (%esp) 
    imull %ecx, %eax 
    movb %al, %dl 
    movl %edx, %eax 
    shrl $7, %eax 
    movl %eax, 20(%esp) 
    movl %edx, %eax 
    shrl $6, %eax 
    andl $1, %eax 
    movl %eax, 16(%esp) 
    movl %edx, %eax 
    andl $31, %edx 
    shrl $5, %eax 
    andl $1, %eax 
    movl %eax, 12(%esp) 
    movl %edx, 8(%esp) 
    call __printf_chk 
    xorl %eax, %eax 
    leave 
    ret 
関連する問題