구조체 최소 크기??

Darkcircle의 이미지

gcc로 bool형을 사용하는 소스를 컴파일하려니 bool형이 없더군요
그래서 다음과 같이 bool형을 정의해 보았습니다. -_-

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef union bitbool{
    char truefalse;
    struct tf{
        unsigned true_false : 1;
        unsigned            : 7;
    } tf;
} bool; // bool 형이 없응께 =_=;

1바이트짜리 bool 형을 만들려고 막상 다 만들어놓고
printf로 sizeof() 를 써서 bool형 사이즈 찍으니까
4바이트로 나오더군요 -_-;

union과 struct 최소 크기가 4바이트 였던가요?
여태껏 프로그램 짜면서 그거 신경 안썼었는데 . . .
이번에 확인해보니까 1바이트가 안되더군요 -_-

무개념의 지존(?) "수다맨" 이 . . .

sozu의 이미지

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

Darkcircle의 이미지

sozu wrote:
혹시 Padding 된것이 아닐까요 :)

http://bbs.kldp.org/viewtopic.php?t=43492&highlight=%C6%D0%B5%F9

Pa . . .Padding 이라 -_-
1바이트짜리 구조체를 만드는건데 . . .

"4byte alignment에 맞지 않기 때문에" 라는 이유는 수긍하겠지만 -_- 어째 좀 이상하네요 . . . -_-
gcc에서 우격다짐으로 4바이트로 늘여버릴리는 없을것 같고 -_-;
게다가 포인터도 아닌데 -_-;;

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

GunSmoke의 이미지

구조체 패딩이 문제가 아닙니다.

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef union bitbool{
    char truefalse;
    struct tf{
        unsigned true_false : 1;
        unsigned            : 7;
    } tf;
} bool; // bool 형이 없응께 =_=;

공용체의 크기는 멤버 중 가장 큰 크기를 갖는 멤버의 크기 이상이 되어야 합니다. sizeof(bool)이 1바이트가 될 것이라고 기대하시면 안됩니다.

먼저 공용체에 대한 개념 이해가 필요합니다.

大逆戰

익명 사용자의 이미지

수다맨 wrote:

gcc에서 우격다짐으로 4바이트로 늘여버릴리는 없을것 같고 -_-;

늘여버릴 수 있습니다. 구조체의 내부에는 padding이 들어갈 수 있지만, 배열의 원소들의 사이사이에는 padding이 들어갈 수 없습니다. 정확하게 배열의 시작주소 + 원소의 크기 = 두번째 원소의 주소가 되어야 합니다. 만약 메모리의 정렬제한을 가진 컴퓨터에서 구조체의 배열을 사용한다고 하면, 모든 배열의 원소들이 정렬제한을 지켜야 합니다.

익명 사용자의 이미지

인텔 32비트 기계의 경우를 생각해 봅시다. 만약 구조체의 크기를 1byte로 한다고 하면 그 구조체의 배열을 사용할때 n+1, n+2, n+3 번째 원소는 정렬제한을 어기게 되어 접근할 때 성능상의 손해를 보게 됩니다. 그러나 구조체의 뒤에 padding 을 3byte 붙여서 4byte로 만들면 컴퓨터 입장에서는 훨씬 쉽게 다룰 수 있게 됩니다.

sozu의 이미지

GunSmoke wrote:
구조체 패딩이 문제가 아닙니다.

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef union bitbool{
    char truefalse;
    struct tf{
        unsigned true_false : 1;
        unsigned            : 7;
    } tf;
} bool; // bool 형이 없응께 =_=;

공용체의 크기는 멤버 중 가장 큰 크기를 갖는 멤버의 크기 이상이 되어야 합니다. sizeof(bool)이 1바이트가 될 것이라고 기대하시면 안됩니다.

먼저 공용체에 대한 개념 이해가 필요합니다.

struct tf

에서 Padding 이 되었을것 같은데.. :oops:

말씀하시는 바에 의하면 tf 는 Bit field 를 사용하였는데 4byte 라는 것이네요~

공용체에 대한 이해는 하신것 같은데 :)

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

pynoos의 이미지

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef union bitbool __attribute__((packed)){
    char truefalse;
    struct tf{
        char true_false : 1;
        char x: 7;
    } tf;
} bool; // bool 형이 없응께 =_=;

pack 하고, unsigned 를 char 로 바꾸면 되지 않을까요?

yui의 이미지

수다맨 wrote:
gcc로 bool형을 사용하는 소스를 컴파일하려니 bool형이 없더군요
그래서 다음과 같이 bool형을 정의해 보았습니다. -_-

다른 얘기지만 bool형은 있습니다.
_Bool, 1, 0을 쓰면 됩니다. 모양이 안이쁘다면 stdbool.h를 포함하고, 쓰던대로 쓰면 됩니다.
$ cat bool.c
#include <stdio.h>
#include <stdbool.h>

int main()
{
        bool a;
        a = true;
        printf("%d\n",a);
}
pynoos의 이미지

_Bool 은 참고로 C99 표준에서 표준화된 것입니다.

GunSmoke의 이미지

sozu wrote:

struct tf

에서 Padding 이 되었을것 같은데.. :oops:

말씀하시는 바에 의하면 tf 는 Bit field 를 사용하였는데 4byte 라는 것이네요~

공용체에 대한 이해는 하신것 같은데 :)

OP의 질문은 sizeof(bool), 즉 사용자가 정의한 union type의 크기를 확인하고 싶다는 것이었죠.
제가 오해했습니다. OP가 기대했던 1byte는 char이 아니라 struct tf의 1byte였군요. 그렇다면 저 역시 구조체 패딩의 가능성이 있다고 생각합니다.

大逆戰

pynoos의 이미지

GunSmoke wrote:
sozu wrote:

struct tf

에서 Padding 이 되었을것 같은데.. :oops:

말씀하시는 바에 의하면 tf 는 Bit field 를 사용하였는데 4byte 라는 것이네요~

공용체에 대한 이해는 하신것 같은데 :)

OP의 질문은 sizeof(bool), 즉 사용자가 정의한 union type의 크기를 확인하고 싶다는 것이었죠.
제가 오해했습니다. OP가 기대했던 1byte는 char이 아니라 struct tf의 1byte였군요. 그렇다면 저 역시 구조체 패딩의 가능성이 있다고 생각합니다.

구조체의 패딩이 아니라, unsigned 이기 때문에 4 byte로 잡히는 것입니다.
bit field를 8bit만 사용한다고 1 byte로 만들지는 않겠죠..

GunSmoke의 이미지

pynoos wrote:

구조체의 패딩이 아니라, unsigned 이기 때문에 4 byte로 잡히는 것입니다.
bit field를 8bit만 사용한다고 1 byte로 만들지는 않겠죠..

음 그렇군요. 그래서 구조체 내의 멤버를 char로 선언해 준 것이군요...

大逆戰

전웅의 이미지

sozu wrote:
에서 Padding 이 되었을것 같은데..

말씀하시는 바에 의하면 tf 는 Bit field 를 사용하였는데 4byte 라는 것이네요~

공용체에 대한 이해는 하신것 같은데

해당 컴파일러가 bit-field 를 위한 storage unit 으로 4 bytes 크기를
선택한 이상 padding 과는 무관합니다. 따라서 어찌되었든 처음 GunSmoke
님의 답변이 맞습니다.

GunSmoke wrote:
공용체의 크기는 멤버 중 가장 큰 크기를 갖는 멤버의 크기 이상이 되어야 합니다. sizeof(bool)이 1바이트가 될 것이라고 기대하시면 안됩니다.

먼저 공용체에 대한 개념 이해가 필요합니다.

bit-field 를 위한 메모리 할당을 위해 각 implementation 은 자기
나름대로의 필요에 따라 적절한 크기의 addressable storage unit 을
도입할 수 있습니다. 물론, 가장 간편하게는 해당 시스템의 word 에 맞도록
하는 것이지만, bit-field 의 type 이 signed/unsigned int 라고 해서 그
storage unit 의 크기도 sizeof(int) 가 될 것이라 생각해서는 안 됩니다.
예를 들어, 어떤 implementation 에서 메모리 정렬 제한으로 얻을 수 있는
이득이 없고, 두 storage unit 사이로 한 bit-field 멤버가 걸칠 수
있다면, unsigned foo:8 이라는 멤버에 1 byte 크기의 storage unit 을
할당하는 것도 가능합니다 - 이 경우 그 bit-field 멤버만을 갖는 구조체의
크기는 1 byte 가 될 수 있습니다.

pynoos wrote:
pack 하고, unsigned 를 char 로 바꾸면 되지 않을까요?

pack 은 물론 bit-field 를 unsigned/signed int 외에 다른 데이터형으로
선언하는 것 역시 이식성을 제한합니다.

implementation 이 bit-field 를 unsigned/signed char 로 선언하는 확장과
_Bool 의 지원 두 가지 선택을 제공한다면, 장래를 생각해 _Bool (혹은
<stdbool.h>) 를 선택하는 것이 나을 것 같습니다.

그럼...

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

pynoos의 이미지

C89나 C99 표준이 bit field가 차지할 공간에 대해 명확하지 않은가 보군요.

어찌 되었건.. bool 형이 1 byte 짜리어야한다든지, 4 byte 여야하든지, 아니면 심지어 1 bit 여야하든지는 신경쓰지 않아도 이식성이 좋으면 상관없겠지만, 다른 많은 C99 표준처럼 현상황에서 앞으로 10년(어쩌면 더)은 신경쓰일 문제입니다.

lsj0713의 이미지

저기 위에 손님으로 글 쓴 사람이 저인지라 확실히 하는게 좋을 것 같아서... :-)

전웅님 말이 맞습니다. 최소한 gcc에서만큼은 padding 문제가 아니라 bit-field 구조체의 크기 문제입니다. 틀린 답변을 올려서 죄송합니다 -_-;

#include <stdio.h>

union A
{
    char a1;
    unsigned char a2[3];
} a[2];

struct B
{
    char b1[2];
    char b2;
} b;

struct G {
    unsigned int h:1;
    unsigned int i:7;
} g;

union C
{
    char a;
    struct D {
        unsigned int e:1;
        unsigned int f:7;
    } d;
} c;

int main(void)
{
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(b));
    printf("%d\n", sizeof(c));
    printf("%d\n", sizeof(g));
    return 0;
}

정렬제한 때문이라고 생각했는데 그다지 강력하게 제한받지는 않는 것 같군요.

하여간 gcc에서의 특성을 정리해보자면

1) 구조체 맴버들의 시작주소는 정렬제한을 지킨다. 단 char형이 아닌 경우에만.
2) 구조체의 크기가 꼭 4의 배수일 필요는 없다. 구조체의 맴버가 전부 char형인 경우에는 4의 배수가 아닐 수도 있다. (어차피 무의미하기 때문일까요?)
3) 비트필드 구조체는 반드시 4의 배수 크기를 갖는다.

1, 2번은 이해가 가는데 3번의 경우에는 굳이 정렬제한을 지킬 필요가 있는지 궁금하군요. 어차피 별도의 처리과정을 거쳐야 되는 만큼 정렬제한이 무의미하지 않을까요?

Darkcircle의 이미지

음 . . 위에 어떤분 말씀대로 unsigned에 문제가 있는듯 싶어서 자료형을 뜯어봤습니다. -_-

일단 sizeof(unsigned) 해서 사이즈 조사를 해봤습니다. 기본 크기가 4바이트였습니다. 컥 -_-;
사이즈 문제를 걸고 넘어가고 나니 표현 범위가 의심스러워서 다음과 같은 소스를 썼습니다. -_-

unsigned l;

for(l=1;l<2147483647;l*=2){
    printf("%d\n",l-1);
}

요놈이 가만히 보고 있자하니 int 형이랑 똑같습니다. 구현가능한 최대값은 2147483647 최소값은 -2147483648입니다. limits.h에는 정의된 값이 없는것 같더라고요 . . UINT_MAX가 정의되어 있긴 합니다만 이거와는 상관이 없습니다. 한마디로 unsigned 와는 전혀 상관 없는 -_-;; 부호화된 값이 튀어나옵니다. 마지막값인 -2147483648에서 -1을 더하려면 더이상의 최소값을 찾을 수가 없어서 그냥 그대로 찍혀나옵니다.

직접 해보시길 -_- . . .

위에 명시된 큰 값을 직접적으로 할당하려고 하면 ISO C90 규칙 위반으로 할당 문제가 발생합니다. (글고보니 컴파일러가 C90 표준으로 컴파일 합니다 -_-)아무래도 똥꼬집은 자제해야겠습니다 . . 헛 ㅡㅛ-)>

어쨌거나 stdbool.h가 눈씻고 찾아봐도 보이질 않아서 이부분은 포기했습니다.;; -_-
unsigned 를 char로 바꿔보니 사이즈문제는 해결이 되었습니다.
(비트필드멤버를 char형으로 하면 전체 사이즈가 1이 될 수도 있습니다.)
공용체 할당값 검사도 해봤습니다. 문제는 0 하고 1만 들어가야 하는데
컴파일러에서 문제삼지 않고 그냥 넘어가더군요 -_-
뭐가 문제가 있는건지 아직도 삽질중입니다.

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

krisna의 이미지

그런데 요점은 단지 bool 형을 사용하는 것이라면
위의 복잡한 구조체를 사용하거나 1 byte 크기의 변수를 사용하는 것보다는 그냥 int형을 사용하는 것이 더 좋을 것 같군요.

Darkcircle의 이미지

krisna wrote:
그런데 요점은 단지 bool 형을 사용하는 것이라면
위의 복잡한 구조체를 사용하거나 1 byte 크기의 변수를 사용하는 것보다는 그냥 int형을 사용하는 것이 더 좋을 것 같군요.

음 . . 전 단지 사용하는데 목적을 두기 위한것 뿐만이 아닙니다.
초기 질문에서 빠진 재정의 및 사용의도가 있습니다.
메모리 사용 차원에서 사용량의 최소화를 꾀하려고 그런겁니다.

P.S. 음 . . 어떻게 찾다보니 stdbool.h를 쓰지 않아도
_Bool 형이란게 있어서 이걸로 쓸 수 있더군요 -_-/
_Bool이 예약어라면 어딘가 정의되어 있을텐데 . . . ㅡ_-)> . . .

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

krisna의 이미지

수다맨 wrote:
krisna wrote:
그런데 요점은 단지 bool 형을 사용하는 것이라면
위의 복잡한 구조체를 사용하거나 1 byte 크기의 변수를 사용하는 것보다는 그냥 int형을 사용하는 것이 더 좋을 것 같군요.

음 . . 전 단지 사용하는데 목적을 두기 위한것 뿐만이 아닙니다.
초기 질문에서 빠진 재정의 및 사용의도가 있습니다.
메모리 사용 차원에서 사용량의 최소화를 꾀하려고 그런겁니다.

P.S. 음 . . 어떻게 찾다보니 stdbool.h를 쓰지 않아도
_Bool 형이란게 있어서 이걸로 쓸 수 있더군요 -_-/
_Bool이 예약어라면 어딘가 정의되어 있을텐데 . . . ㅡ_-)> . . .

진짜로 int 형을 그대로 쓰라는 뜻은 아니었습니다.

typedef enum {
    FALSE = 0,
    TRUE = 1
} BOOL;

저는 이런 간단한 정의가 더 편할것이라는 생각이었습니다.

그리고 위의 bool 타입의 경우

bool is_not_null(void *ptr) { return ptc != NULL; }

이런 형태의 코드가 가능할지 궁금하군요.

그리고 char형이라고 해서 메모리를 적게 사용할지는 모르겠군요.
일반적인 함수의 변수라면 메모리 사용이 문제될일은 많지 않을것 같구요.
전역 변수라해도 메모리 사용이 줄어들지는 않을 것 같습니다.
(물론 bool형인 초대형 배열이 있다면 이야기는 다르지만요 :)

그리고 속도도 int형이 char형이나 같거나 빠를 겁니다.

_Bool은 위에서 다른 분들이 이야기 한 것입니다.

익명 사용자의 이미지

수다맨 wrote:
음 . . 위에 어떤분 말씀대로 unsigned에 문제가 있는듯 싶어서 자료형을 뜯어봤습니다. -_-

일단 sizeof(unsigned) 해서 사이즈 조사를 해봤습니다. 기본 크기가 4바이트였습니다. 컥 -_-;

unsigned 는 unsigned int 형입니다. signed int 형과 unsigned int 형의 크기가 같은 것은 이상한 일이 아닙니다.

수다맨 wrote:

unsigned l;

for(l=1;l<2147483647;l*=2){
    printf("%d\n",l-1);
}

요놈이 가만히 보고 있자하니 int 형이랑 똑같습니다. 구현가능한 최대값은 2147483647 최소값은 -2147483648입니다.

unsigned int형을 출력하기 위해서는 "%u"를 써야 합니다. printf 함수가 매개변수의 타입과 갯수를 알아내는 유일한 방법은 포맷 문자열 뿐입니다(가변 인자 함수의 특성입니다). 포맷 문자가 잘못되면 printf는 넘겨진 매개변수를 제대로 해석하지 못합니다.

수다맨 wrote:

unsigned 를 char로 바꿔보니 사이즈문제는 해결이 되었습니다.
(비트필드멤버를 char형으로 하면 전체 사이즈가 1이 될 수도 있습니다.)

이식성을 보장받을 수 있는 방법은 int, unsigned int, _Bool 뿐입니다.

수다맨 wrote:

음 . . 전 단지 사용하는데 목적을 두기 위한것 뿐만이 아닙니다.
초기 질문에서 빠진 재정의 및 사용의도가 있습니다.
메모리 사용 차원에서 사용량의 최소화를 꾀하려고 그런겁니다.

메모리 사용을 줄이기 위해서라면 char/unsigned char형을 사용하시는 것이 좋습니다. 어쨌든 무조건 sizeof(1), 즉 1byte가 되는 것이 보장이 됩니다. bool이라고 해서 반드시 2가지 값'만'을 표현 가능할 필요는 없습니다. 또한 위에서 보시는 대로 비트 필드 구조체를 사용한다고 해서 메모리 사용량이 줄어드는 것도 아닙니다. 아니면 자체적으로 비트 연산을 해서 unsigned char형 하나당 8개의 bool 값을 저장하는 bool_array(?)를 만들 수도 있겠습니다만...

Darkcircle의 이미지

손님 wrote:
수다맨 wrote:
음 . . 위에 어떤분 말씀대로 unsigned에 문제가 있는듯 싶어서 자료형을 뜯어봤습니다. -_-

일단 sizeof(unsigned) 해서 사이즈 조사를 해봤습니다. 기본 크기가 4바이트였습니다. 컥 -_-;

unsigned 는 unsigned int 형입니다. signed int 형과 unsigned int 형의 크기가 같은 것은 이상한 일이 아닙니다.

수다맨 wrote:

unsigned l;

for(l=1;l<2147483647;l*=2){
    printf("%d\n",l-1);
}

요놈이 가만히 보고 있자하니 int 형이랑 똑같습니다. 구현가능한 최대값은 2147483647 최소값은 -2147483648입니다.

unsigned int형을 출력하기 위해서는 "%u"를 써야 합니다. printf 함수가 매개변수의 타입과 갯수를 알아내는 유일한 방법은 포맷 문자열 뿐입니다(가변 인자 함수의 특성입니다). 포맷 문자가 잘못되면 printf는 넘겨진 매개변수를 제대로 해석하지 못합니다.

저런 . . . 제가 결정적인 실수를 -_-;
요롷게 고쳐보니 4294967295가 무한반복되는군요 -_-

unsigned l;

for(l=1;l<2147483647;l*=4){
    printf("%d\n",l-1);
}

(상한값이 이거란 얘긴데 -_-;; 왜 멈추질 않는걸까 . . . )

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

lsj0713의 이미지

수다맨 wrote:
(상한값이 이거란 얘긴데 -_-;; 왜 멈추질 않는걸까 . . . )

C에서의 무부호 정수형(unsigned char, unsigned int, unsigned long, etc)은 절대로 overflow가 발생하지 않습니다. 표현범위보다 큰 수가 될 경우엔 나머지 연산의 결과값이 들어가게 되어 있습니다. unsigned int의 경우 n % (UINT_MAX + 1) 이 되겠죠.

GunSmoke의 이미지

전웅 wrote:

...
해당 컴파일러가 bit-field 를 위한 storage unit 으로 4 bytes 크기를
선택한 이상 padding 과는 무관합니다. 따라서 어찌되었든 처음 GunSmoke
님의 답변이 맞습니다.
...

부끄러운 일이 아닐 수 없습니다.
스스로 자기 답변에 대해 정/오를 확신할 능력이 없는 사람이 남의 질문에 답을 하려고 하다니...
더 열심히 공부해야겠음을 느낍니다.

PS. 제가 귀가 좀 얇죠;;

大逆戰

익명 사용자의 이미지

쭉 읽어보니 제가 공부할게 아직도 상당히 많음을 느꼈습니다.

물론 이 과정에서 잘못된 답변을 해주시면서 각자분들도 느끼셨겠지만

C/C++이 . . . -_- . . . 정말 끊임 없이 배워야만 하는

그런 도구가 아닌가 싶습니다. :)

방에 틀어박혀서 C 책을 새로 구해서 읽어봐야겠군요 :)

Darkcircle의 이미지

Anonymous wrote:
쭉 읽어보니 제가 공부할게 아직도 상당히 많음을 느꼈습니다.

물론 이 과정에서 잘못된 답변을 해주시면서 각자분들도 느끼셨겠지만

C/C++이 . . . -_- . . . 정말 끊임 없이 배워야만 하는

그런 도구가 아닌가 싶습니다. :)

방에 틀어박혀서 C 책을 새로 구해서 읽어봐야겠군요 :)

아 이 위에거 제가 쓴건데 . . 요즘 자동로긴이 안되니 영 골치가 아프군요 :(;;

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

전웅의 이미지

lsj0713 wrote:
1) 구조체 맴버들의 시작주소는 정렬제한을 지킨다. 단 char형이 아닌 경우에만.
2) 구조체의 크기가 꼭 4의 배수일 필요는 없다. 구조체의 맴버가 전부 char형인 경우에는 4의 배수가 아닐 수도 있다. (어차피 무의미하기 때문일까요?)
3) 비트필드 구조체는 반드시 4의 배수 크기를 갖는다.

1, 2번은 이해가 가는데 3번의 경우에는 굳이 정렬제한을 지킬 필요가 있는지 궁금하군요. 어차피 별도의 처리과정을 거쳐야 되는 만큼 정렬제한이 무의미하지 않을까요?

1번을 생각하면 2번은 당연합니다.

3번의 경우 gcc 는 비트 필드를 위한 stroage unit 으로 시스템 워드를
선택한 것입니다. 즉, 어디까지나 implementation 선택의 문제일 뿐입니다.

제가 기억하기로는 gcc 에서 비트 필드가 두 storage unit 사이에 걸칠 수
없는 것으로 알고 있습니다 (정확하진 않으니 궁금하신 분은 직접
확인하시기 바랍니다). 이 경우 표준의 요구에 의해 비트 필드를 위한
storage unit 을 최소 (signed/unsigned int 를 위한) 워드 크기로 잡을 수
밖에 없습니다. 더구나 확장으로 unsigned/signed char 를 제공하는
상황에서 할당되는 비트 필드의 크기에 따라 storage unit 의 크기를
가변적으로 처리해 줄 필요성은 없는 것 같습니다.

수다맨 wrote:
음 . . 위에 어떤분 말씀대로 unsigned에 문제가 있는듯 싶어서 자료형을 뜯어봤습니다. -_-

일단 sizeof(unsigned) 해서 사이즈 조사를 해봤습니다. 기본 크기가 4바이트였습니다. 컥 -_-;

한 가지 유의하셔야 할 사실은 비트 필드 선언에 사용되는 signed/unsigned
int 를 실제 정수형인 signed/unsigned int 와 직접적으로 연결지어서는 안
된다는 것입니다. 처음 예에서도 설명 드렸듯이,

sizeof(struct { unsigned foo:8; })

의 결과가 1 이 나오는 implementation 도 가능합니다. 또 다른 예로 비트
필드 선언에 signed 나 unsigned 없이 "plain" int 를 형지정자로 써주는
경우, unsigned int 로 처리될 수도 있습니다. 중요한 것은 표준이 비트
필드 선언 시에 사용할 수 있는 형지정자를 signed/unsigned int 로
제한하고 있다는 사실입니다.

수다맨 wrote:
_Bool이 예약어라면 어딘가 정의되어 있을텐데 . . . ㅡ_-)> . . .

int 도 _Bool 과 동일한 예약어 (reserved word, keyword) 입니다. int 는
어디에 정의되어 있을까요? ^^

비트 필드를 사용하든 int 나 char 를 사용하든 C 언어의 표준 정수형을
사용한 boolean type 구현은 C99 가 제공하는 _Bool 과는 차이가 있습니다.
예를 들어,

_Bool b;
int i;
int *pi = &i;

b = 0.5;    /* b = 1; */
i = 0.5;    /* i = 0; */

b = pi;     /* b = 1; */
i = pi;     /* wrong */
i = (int) pi;    /* not portable */

pi = 0;    /* null pointer */
b = pi;     /* b = 0; */
i = pi;     /* wrong */
i = (int) pi;    /* not portable */

이 정도면 굳이 _Bool 이 제공되는 상황에서 불완전한 boolean type 구현의
필요성이 싹 사라지지 않습니까?

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

sozu의 이미지

pynoos wrote:
GunSmoke wrote:
sozu wrote:

struct tf

에서 Padding 이 되었을것 같은데.. :oops:

말씀하시는 바에 의하면 tf 는 Bit field 를 사용하였는데 4byte 라는 것이네요~

공용체에 대한 이해는 하신것 같은데 :)

OP의 질문은 sizeof(bool), 즉 사용자가 정의한 union type의 크기를 확인하고 싶다는 것이었죠.
제가 오해했습니다. OP가 기대했던 1byte는 char이 아니라 struct tf의 1byte였군요. 그렇다면 저 역시 구조체 패딩의 가능성이 있다고 생각합니다.

구조체의 패딩이 아니라, unsigned 이기 때문에 4 byte로 잡히는 것입니다.
bit field를 8bit만 사용한다고 1 byte로 만들지는 않겠죠..

제가 잘못보고 답변 한것 같습니다. :oops:

순간적으로 unsigned char 로 보았네요;;;

아..실수투성이~

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

bejoy4him의 이미지

padding이야기가 나와서 한가지 물어보고싶습니다

정렬제한이 있는 머신에서 (sparc/솔라리스9)
pragma pack(1)을 사용하여 padding을 하지 못하게 하고있는 소스를
포팅하려고 하는데...
자꾸만 bus error가 발생합니다.

뭐 gdb를 사용하면 구조체의 멤버의 시작주소가 odd번지이고 그것을 long이나 short를 이용하여 읽을려고 하니 bus-error가 발생하는것은 당연한듯 보입니다만, 컴파일러 옵션을 통해서라도 그것을 어떻게 막을수는 없는것일까요?

구조체를 수정한다면야 간단하겠지만.... 현실적으론 불가능에 가깝습니다. 현재 포팅하고 있는 소스뿐만이 아니라 이것과 연동되는 많은 어플리케이션이 바뀌어야 합니다.

정말 방법이 없을까요? 직접적인 해결방법이 없다면 가장 현실적인 방안은 어떤게 될수 있을런지???
첩첩 산중입니다.

익명 사용자의 이미지

Quote:

OP가 기대했던 1byte는 char이 아니라 struct tf의 1byte였군요

char 도 1byte 아닌가요?

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.