2013-07-01 1 views
0

다음 코드를 실행할 때 이상한 동작을 관찰하고 있습니다. 구조체를 사용하여 bitfield를 만들면 52 비트를 사용하므로 long int를 사용합니다. long int의 크기는 시스템에서 64 비트이며 코드 내부에서 확인합니다. 어떻게 든 하나의 비트를 설정하려고하면 alwas가 2 비트를 설정합니다. 그들 중 하나가 제가 설정하고 싶었던 것이고 두 번째 것은 첫 번째 플러스 32의 인덱스입니다. 칸 아무나 말해줘, 왜 그거야?struct에서 long int를 사용하는 bitfields 이상한 동작

8

0

32

: 내 질문이 basicly 이해할 수 없었다, 그래서

#include <stdio.h> 

typedef struct foo { 
    long int x:52; 
    long int:12; 
}; 

int main(){ 
    struct foo test; 
    int index=0; 
    printf("%ld\n",sizeof(test)); 
    while(index<64){ 
    if(test.x & (1<<index)) 
     printf("%i\n",index); 
    index++; 
    } 
    test.x=1; 
    index=0; 
    while(index<64){ 
    if(test.x & (1<<index)) 
     printf("%i\n",index); 
    index++; 
    } 
    return 0; 
} 

SRY가, 출력을 게시하는 것을 잊었다 ... 그것은 나를 준다 출력은 다음과 같다

+0

게시 한 코드의 동작이 정의되지 않았습니다. (초기화하기 전에'test.x'에 접근합니다.) 그래서 어떤 일이 일어날 수 있습니다. –

답변

5

indexint이며, 이는 시스템에서 32 비트 일 수 있습니다. 해당 유형의 비트 수보다 크거나 같은 양만큼 값을 이동하면 정의되지 않은 동작이 발생합니다.

변경 index ~ unsigned long (비트 이동 부호있는 유형은 권장하지 않음). 또는 1<<index1L << index 또는 심지어 1LL << index으로 변경할 수 있습니다.

다른 사람들이 지적한대로 test은 초기화되지 않았습니다. 이 같은 모두 0으로 초기화 할 수 있습니다 size_t에 대한

struct foo test = { 0 }; 

올바른 printf 형식 %zu하지 %ld입니다.

long이 64 비트라는 이식 불가능한 가정에 의존하지 않도록 코드를 수정하는 것이 좋지 않을 것입니다. 32 비트만큼 좁을 수 있습니다. <stdint.h>에 정의 된 uint_N_t 유형을 사용하는 것이 좋습니다.

또한 intunsigned int, signed int_Bool (또는 bool가) 구현에 정의 된 이외의 다른 유형의 비트 필드를 언급해야한다.

+0

고마워요,이 답변은 정말 유익한 내 문제를 완전히 해결, 나는 또한 귀하의 advisis를 사용합니다! – zabeltech

1

구조를 초기화하지 않고 text.x의 비트를 검사하면 코드에서 정의되지 않은 동작이 발생합니다. 변수를 초기화하지 않으므로 임의의 데이터가 포함됩니다.

+0

사실,하지만 그것은 아마도 그가 보는 증상의 원인이 아닙니다. –

+0

@KeithThompson 글쎄, 그것은 정의 할 수없는 행동이므로, 말할 방법이 없다.) –

+1

원칙적으로 참이지만'test '가 처음에는 0 비트가되고'int'가 32 비트라고 가정하면 ,'1 << index'의 다른 * 정의되지 않은 동작은 그가 보는 행동을 설명합니다. –