programing

C에 ()의 크기에 해당하는 비트가 있습니까?

testmans 2023. 10. 12. 22:16
반응형

C에 ()의 크기에 해당하는 비트가 있습니까?

비트 필드에 적용할 때는 ()의 크기가 작동하지 않습니다.

# cat p.c
  #include<stdio.h>
  int main( int argc, char **argv )
  {
    struct { unsigned int bitfield : 3; } s;
    fprintf( stdout, "size=%d\n", sizeof(s.bitfield) );
  }
# gcc p.c -o p
  p.c: In function ‘main’:
  p.c:5: error: ‘sizeof’ applied to a bit-field

...obviously, 부동 소수점의 부분적인 크기 같은 것을 돌려줄 수 없기 때문입니다.하지만, 이것은 흥미로운 질문을 던졌습니다.C에 변수/타입의 비트 수를 알려주는 등가물이 있습니까?이상적으로는 비트 필드 외에 char, int와 같은 일반 유형에도 적용할 수 있습니다.

업데이트:

비트 필드에 대해 () 크기에 해당하는 언어가 없다면 런타임에 가장 효율적으로 계산할 수 있는 방법은 무엇입니까?이것에 의존하는 루프가 있다고 생각해보세요. 그리고 비트 필드의 크기를 변경하고 공정한 부정행위를 하지 않고 비트 필드 크기와 루프 길이를 매크로로 만드는 것을 원하지 않습니다. ;-)

C에서는 비트 필드의 크기를 확인할 수 없습니다.그러나 다른 유형의 비트로 크기를 알 수 있습니다.CHAR_BIT, 에서 발견되는.<limits.h>. 비트 단위의 크기는 단순합니다.CHAR_BIT * sizeof(type).

C 바이트를 옥텟이라고 가정하지 마십시오. 적어도 8비트입니다.16비트 혹은 심지어 32비트 바이트를 가진 실제 기계들이 있습니다.

편집 관련:조금은 과장된 얘기하고 싶습니다.int a: n;는 정의에 따라 n비트의 크기를 갖습니다.스트럭트에 넣을 때 추가 패딩 비트는 스트럭트에 속하며 비트 필드에 속하지 않습니다.

조언:비트 필드를 사용하지 않고 사용( 배열)unsigned char비트마스크로 작업을 하고 있습니다.이렇게 하면 많은 동작(오버플로우, 패딩 없음)이 잘 정의됩니다.

()의 크기를 사용하여 비트 필드의 크기를 찾는 것은 불가능합니다.C99 참조:

  • 6.5.3.4 The sizeof operator, 비트 필드는 크기에 의해 지원되지 않습니다.
  • 6.7.2.1 Structure and union specifiers여기서 비트 필드가 자립 멤버가 아님을 명확히 합니다.

그렇지 않으면 비트 필드 멤버 -1u(모든 비트가 설정된 값)에 할당한 다음 가장 의미 있는 비트의 인덱스를 찾을 수 있습니다.예:(테스트되지 않음):

s.bitfield = -1u;
num_bits = ffs(s.bitfield+1)-1;

man ffs 더 많은 것을 위하여

이 솔루션을 구현했습니다[1].

#include <stdio.h>
#define bitoffsetof(t, f) \
    ({ union { unsigned long long raw; t typ; }; \
    raw = 0; ++typ.f; __builtin_ctzll(raw); })

#define bitsizeof(t, f) \
    ({ union { unsigned long long raw; t typ; }; \
    raw = 0; --typ.f; 8*sizeof(raw)-__builtin_clzll(raw)\
        -__builtin_ctzll(raw); })

struct RGB565 { unsigned short r:5, g:6, b:5; };
int main()
{
    printf("offset(width): r=%d(%d) g=%d(%d) b=%d(%d)\n",
        bitoffsetof(RGB565, r), bitsizeof(RGB565, r),
        bitoffsetof(RGB565, g), bitsizeof(RGB565, g),
        bitoffsetof(RGB565, b), bitsizeof(RGB565, b));
}


$ gcc bitfield test.cpp &/a.out
오프셋(폭): r=0(5) g=5(6) b=11(5)
[1] https://twitter.com/suarezvictor/status/1477697986243272706

업데이트: 컴파일 시간에 이 문제가 해결됨을 확인했습니다.

void fill(int *x)
{
    x[0]=bitoffsetof(RGB565, r);
    x[1]=bitsizeof(RGB565, r);
    x[2]=bitoffsetof(RGB565, g);
    x[3]=bitsizeof(RGB565, g);
    x[4]=bitoffsetof(RGB565, b);
    x[5]=bitsizeof(RGB565, b);
}

어셈블러 출력:

fill:
.LFB12:
    .cfi_startproc
    movl    $0, (%rdi)
    movl    $5, 4(%rdi)
    movl    $5, 8(%rdi)
    movl    $6, 12(%rdi)
    movl    $11, 16(%rdi)
    movl    $5, 20(%rdi)
    ret

#defin 문 집합을 사용하여 구조의 정의에서 비트 너비를 지정한 다음 인쇄할 때와 같은 #defin을 사용합니다.

비트 필드 크기 정의가 전역 이름 공간을 어지럽히지만 '한 번만 정의, 여러 번 사용'은 동일합니다.

# cat p.c
#include<stdio.h>
int main( int argc, char **argv )
{
   #define bitfield_sz 3
   struct { unsigned int bitfield : bitfield_sz; } s;
   fprintf( stdout, "size=%d\n", bitfield_sz );
}
# gcc p.c -o p
# ./p
size=3
#

언급URL : https://stackoverflow.com/questions/3319717/is-there-a-bit-equivalent-of-sizeof-in-c

반응형