uint32_t 이런 type에 대해서
글쓴이: nananahaha / 작성시간: 화, 2014/03/25 - 9:28오전
uint32_t
uint8_t
등등...
인터넷을 검색해본 결과
OS(?)(platform?)마다 int의 크기가 다르기때문에
그 크기를 명시하기위해서 int a; 가 아닌
uint8_t a;
이렇게 정의한다고 설명이 나와있었습니다.
근데
typedef 을 보면
typedef signed int int16_t
이런식으로 나와있습니다.
제가 signed int를 8bit로 정의하는 A라는 platform을 사용하면.. 이름이야 어찌돼었건 int16_t 는 8bit가 할당되는것아닌가요?
그래서 제 생각은... 저렇게 정의한게 무의미하게보인다는겁니다. ㅠㅠ 뭔가 분명 잘못알고있는걸텐데..
알려주세요!!
그리고 용어는 os가 맞나요 platform이 맞나요? .. 모르는게너무많습니다.
Forums:
플랫폼이 바뀌면 저 부분을 새로 선언해줘야죠.
새로 선언해야 하면 의미 없는것 아니냐 하실 수도 있으나, 그래도 한 곳만 수정하면 int16_t가 사용된 코드를 일일이 수정할 필요가 없으니 의미가 있는 것이죠.
물론 보통은 저 부분도 전처리기를 통해 상황에 맞는 typedef를 자동으로 사용할 수 있도록 정의가 되어 있고요.
--
..
컴파일러 또는 cpu의 word단위에 따라 달라지는걸로 알고 있습니다
1년차 임베디드 소프트쟁이 입니다
시스템에 관심이 많습니다
그건 그 typedef를 제공하는 사람이 신경쓸
그건 그 typedef를 제공하는 사람이 신경쓸 일입니다.
미리 정의해놨으니까 믿고 써라 그거죠.
uint8_t같은 표준 해더에서 제공되는 타입은 컴파일러가 알아서 해줍니다.
컴파일러가 제대로 포팅된 플랫폼이라면 그것도 알아서 신경써서 정의해줄겁니다.
그 컴파일러 또는 라이브러리가 signed int가 8bit인 플랫폼으로 포팅이 되었다면, 거기서는 또 다르게 정의하도록 수정이 되겠죠.
그리고 OS 그 자체는 타입을 정의하지 않습니다.
OS의 API등이 어떤 특정한 크기의 정수 타입을 요구할 수는 있겠지만요.
타입을 정의하는 건 언어 스펙이고 이를 구현하는 컴파일러의 문제입니다.
?
질문을 다른 데에 비유하자면 아래와 같습니다.
"자바가 플랫폼 독립적으로 실행된다는데, Windows 에서 현재 동작하는 Java Virtual Machine 프로그램을
리눅스에서 실행 시키려면 어쨌든 리눅스용으로 다시 짜야되는거 아닌가요?ㅠㅠ"
당연합니다. 중요한 건 사용자단(여기선 프로그래머단)에서 내부적으로 변경이 되는 것을
느낄 수 없게 공통적인 환경을 만드는 데에 있습니다.
덧붙여서, 예전 Turbo C 등을 기억하신다면 아시겠지만, 당시 int 는 2바이트 였습니다.
지금은 아시다시피 4바이트인데 이렇게 생각하시면 마치 16비트 CPU 시절엔 int = 2byte 이고
현재 32비트 CPU 일 땐 4byte 인 것으로 착각하실 가능성이 큰데, 사실 그렇지 않습니다.
그 때에서 32비트 시스템으로 전환했을 때는 컴파일러들이 int 의 size도 4바이트가 되도록 하였지만,
지금은 int 는 4바이트로 고정해놓고 새로운 8바이트 타입인 long long 을 쓰도록 하고 있습니다.
즉 만약 32비트 CPU 타겟으로 long long 을 써서 컴파일한다면 이 타입은 하나의 레지스터에
바로 들어가서 연산될 수 없고, 또한 메모리에 한 번에 store 되거나 access 할 수 없습니다.
그래서 이것을 처리하기 위해 명령이 더 길어지고, 당연히 연산 속도도 64bit 타겟 코드에 비해 매우 느립니다.
반면 64bit 타겟으로 컴파일하면 깔끔하게 AMD64 기준으로 rax rbx 등의 레지스터에 한 번에
저장될 수 있으니 명령도 짧아지고 속도도 당연히 빠르게 됩니다. 결국 이 부분에서 착각할 수 있는 것은
64비트 타겟으로 하면 int 가 8바이트가 된다 라고 착각할 수 있지만 현재는 그렇지 않습니다.
다만 포인터 타입의 경우 타입 크기가 반드시 바뀌어야 하기 때문에 컴파일 타겟 플랫폼에 따라서
그냥 바뀝니다. 따라서 절대로 포인터 타입의 크기에 의존적일 수 있는 코드를 짜면 안됩니다.
>> 따라서 절대로 포인터 타입의 크기에 의존적일 수
>> 따라서 절대로 포인터 타입의 크기에 의존적일 수 있는 코드를 짜면 안됩니다.
절대로 안된다기 보다는 포인터의 크기가 얼마일거라고 가정하고 짜면 안된다는 뜻이겠죠?
포인터 변수값을 저장할 수 있는 변수 타입으로 표준에서 이미 intptr_t와 uintptr_t를 제공해주니까 이걸 이용하거나 하드코딩된 값이 아닌 sizeof를 이용한 값을 활용하면 됩니다.
?
말씀하신 그런 의미입니다. 굳이 이런 얘기를 덧붙인 이유는 제가 예전에 유지보수를 하면서
char **a; a = (char **)malloc(4000); for( i = 0; i < 1000; i++ ) a[i] = (int *)malloc(1000);
와 같은 코드를 굉장히 빈번하게 봐왔기 때문입니다. 위와 같은 명시적으로 단순한 부분이 아니라
포인터 타입 크기가 4라는 것을 암시적으로 써서 64비트 타겟 빌드하면 런타임 오류가 왜 나는지 찾기도 힘든 부분이 많았습니다.
위의 내용에 따라서 코드 예시 입니다. #if
위의 내용에 따라서 코드 예시 입니다.
#if defined _ARM_
typedef unsigned int uint32_t;
#elif defined _MPIS_
typedef unsigned long uint32_t;
#endif
대충 이런식으로 만듭니다.
태클 사절 그냥 예시 입니다.
댓글 달기