비트필드 선언시 이상한 현상

hie의 이미지


이상한 현상이 발생하여 이렇게 질문을 드립니다.

#include <stdio.h>
 
 
#pragma pack(1)
 
typedef union u_one_byte
{
        unsigned char value;
 
        struct
        {
                unsigned char upper : 4;
                unsigned char lower : 4;
        } bit;
}one_byte_u;
 
#pragma pack()
 
 
int main()
{
        one_byte_u      one_byte;
 
        one_byte.value = 0xab;
        printf( "\n Upper = 0x%x", one_byte.bit.upper );
        printf( "\n Lower = 0x%x\n", one_byte.bit.lower );
        fflush( stdout );
 
        return( 0 );
}

결과는 다음과 같습니다.

 Upper = 0xb
 Lower = 0xa

저의 예상은 Upper 값이 0xa, Lower 값이 0xb 이었습니다.
제가 착각을 하는 것일까요??

참고로 작업 환경은 다음과 같습니다.

lix19:~/TEST$ uname -an
Linux lix19 2.4.21-47.ELsmp #1 SMP Wed Jul 5 20:38:41 EDT 2006 i686 i686 i386 GNU/Linux
lix19:~/TEST$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-56)

고견 부탁드립니다.

전웅의 이미지

큰 것을 조각으로 나누면 항상 어느 것이 먼져냐는 순서의 문제가 발생
합니다.

왜 구조체 비트 필드 선언에서 위에(먼저) 선언된 멤버가 high-order 라고
가정하시죠? 높이(high) 있다고 해서 high-order 인 것은 아닙니다. :-)

바이트보다 큰 단위를 바이트로 나누면 byte order 가 생기듯이 바이트를
비트로 나누면 bit order 가 생깁니다. 구현에 따라 byte order, bit order
모두 제 각각일 수 있습니다만 보통은 bit order 역시 byte order 를
따라가도록 구현합니다 - 일반적으로 byte order 는 온전히 컴파일러의
영향을 받지 않지만, bit order 는 온전히 컴파일러의 영향을 받습니다.

[* 정작 중요한 내용을 빼먹어 아래 첨언합니다]

구조체에서 먼저 선언된 비트 필드가 high-order 부터 할당될지, low-
order 부터 할당될지는 구현체에 의존적인 사항입니다. 각 구현체의
매뉴얼 등에서 이를 명시하게 됩니다.

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

hie의 이미지

먼저 명쾌한 답변 감사 드립니다.

제가 착각을 했습니다. 조금 더 논리적으로 생각해보았다면
질문을 올리지 않았을지 모르는데..

다시금 답변 감사드립니다. 미소로 시작되는 주말 되십시요.

appler의 이미지

성함이 전웅님이라면...

혹시
C 언어 펀더맨탈 쓰신분?? ^^

-------------------------------
궁금증으로 가득찬 20후반 -_-;;
탄생은 죽음의 시작에 불과하다.

블로그
http://azdream.egloos.com
http://koreaappler.blogspot.com

검색엔진
http://applersearchengine.topicle.com/


laziness, impatience, hubris

不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.

monovision의 이미지

맞습니다. C 에 대한 난해한 주제가 생길때 자주 등장하시죠 ㅎㅎ.

appler의 이미지

역시 한국의 IT 미래는 밝군요..

저도 책하나 쓸만큼의 실력을 갖고 싶어요../(-_-/) 뜨아~

<------ 시스너쳐 ------> 3가지 미덕 : 게으름(laziness), 조급성(impatience), 자기 과신(hubris)


laziness, impatience, hubris

不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.

Hyun의 이미지

[parkhw00@rose0 parkhw00]$ cat test.c
#include <stdio.h>
 
#pragma pack(1)
 
typedef union u_one_byte
{
        unsigned char value;
 
        struct
        {
                unsigned char upper : 4;
                unsigned char lower : 4;
        } bit;
}one_byte_u;
 
#pragma pack()
 
int main()
{
        one_byte_u      one_byte;
 
        one_byte.value = 0xab;
        printf( "\n Upper = 0x%x", one_byte.bit.upper );
        printf( "\n Lower = 0x%x\n", one_byte.bit.lower );
        fflush( stdout );
 
        return( 0 );
}
[parkhw00@rose0 parkhw00]$ gcc test.c
[parkhw00@rose0 parkhw00]$ ./a.out
 
 Upper = 0xa
 Lower = 0xb
[parkhw00@rose0 parkhw00]$ uname -a
SunOS rose0 5.8 Generic_117350-35 sun4u sparc SUNW,Sun-Fire-880
[parkhw00@rose0 parkhw00]$

흠... 요 sparc에선 님께서 의도한대로(?) 나오네요...
경험상 Big endian machine에선 먼저 선언한게 상위로, Little endian machine에선 반대로 되던거 같습니다...
appler의 이미지

아님 컴파일러?

______________________________
궁금증으로 가득찬 20후반 -_-;;
탄생은 죽음의 시작에 불과하다.

블로그
http://azdream.egloos.com
http://koreaappler.blogspot.com

검색엔진
http://applersearchengine.topicle.com/


laziness, impatience, hubris

不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.

Hyun의 이미지

cpu의 아키텍처에 따라 틀리다는 말이죠.
보통 사용하는 pc, i386 계열은 little endian을 사용하구요,
ppc 등은 big endian을 사용합니다.

appler의 이미지


박현우님 설명과 함께 바로 이해해 버렸군요..

근데 확실히 little endian 으로 진행되는건가요??

다르게 될수 도 있다고 보지만.....

일단 저도 하위 4비트 먼저 치환해 사용하므로

님과 같은 생각이지만..

^^ 솔직히 쓰기 두려워 지는군요.ㅎ.ㅎ

<------ 시스너쳐 ------> 3가지 미덕 : 게으름(laziness), 조급성(impatience), 자기 과신(hubris)


laziness, impatience, hubris

不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.

Hyun의 이미지

크로스 플랫폼을 사용하기 위해서 예를들면 아래와 같이 endian별로 다른 매크로를 선언해서 사용합니다. 통신이나 파일포멧을 다루는 쪽에선 비트필드를 많이사용하니깐 저런방법을 종종 사용하는 듯 합니다.

#if __BYTE_ORDER == __BIG_ENDIAN
#define EBIT2(x1,x2) x1 x2
#define EBIT3(x1,x2,x3) x1 x2 x3
#define EBIT4(x1,x2,x3,x4) x1 x2 x3 x4
#define EBIT5(x1,x2,x3,x4,x5) x1 x2 x3 x4 x5
#define EBIT6(x1,x2,x3,x4,x5,x6) x1 x2 x3 x4 x5 x6
#define EBIT7(x1,x2,x3,x4,x5,x6,x7) x1 x2 x3 x4 x5 x6 x7
#define EBIT8(x1,x2,x3,x4,x5,x6,x7,x8) x1 x2 x3 x4 x5 x6 x7 x8
#else
#define EBIT2(x1,x2) x2 x1
#define EBIT3(x1,x2,x3) x3 x2 x1
#define EBIT4(x1,x2,x3,x4) x4 x3 x2 x1
#define EBIT5(x1,x2,x3,x4,x5) x5 x4 x3 x2 x1
#define EBIT6(x1,x2,x3,x4,x5,x6) x6 x5 x4 x3 x2 x1
#define EBIT7(x1,x2,x3,x4,x5,x6,x7) x7 x6 x5 x4 x3 x2 x1
#define EBIT8(x1,x2,x3,x4,x5,x6,x7,x8) x8 x7 x6 x5 x4 x3 x2 x1
#endif
 
struct section {
        uint8_t table_id;
  EBIT4(uint16_t syntax_indicator       : 1; ,
        uint16_t private_indicator      : 1; , /* 2.4.4.10 */
        uint16_t reserved               : 2; ,
        uint16_t length                 :12; );
} __ucsi_packed;

http://linuxtv.org/hg/dvb-apps/file/2686c080e0b5/lib/libucsi/

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.