2009. 4. 10. 11:12

int, int16, int32


C언어가 사이즈에 대한 정확한 정의 없이 typedef를 통해 제공하기 때문에 정확한 사이즈를 제어하기 위해
int16, int32를 명시하여 쓰는 경우가 많다. 하지만 int16, int32를 쓰는 목적이 적어도 이만큼의 크기를 보장하기
위해 쓰는 것이라면 전혀 의미가 없다. int정의 자체가 적어도 16bit 또는 32bit를 뜻하기 때문이다.

어느 사이즈가 고정된 특정 시스템에서 가독성이나 정확한 size제어가 필요하다면(Shift 사이즈 고정 연산이나...) 쓰는 것이 괜찮겠지만, 일반적인 경우는 의미가 없고 자칫 int와 int32가 혼동되어 사용되어 가독성이나 프로그램의 호환성, 안정성이 오히려 떨어질 수 있다.

프로그램의 특성을 잘 계획하고 판단하여 쓰는 것이 바람직 하겠다.
2009. 4. 10. 10:35

extern 선언에 대한 컴파일러의 인식과 링크

요즘에 코딩을 한지 너무 오래되서 적을 만한게 없다..ㅡㅡ;;;
애들 코드리뷰를 하면서 보았던 문제점에 대해 적어 보련다.ㅎㅎ


extern는 다른 파일에 선언되어 있는 전역변수에 대한 링크 시킨다는 의미이다.

extern 변수 선언시 변수의 타입을 기입하지 않는 경우가 있는데 이때 컴파일러는 type checjing작업을 통해
묵시적으로 사용된 값에 대한 타입을 예상하게 된다. 이는 곧 타입에 대한 기재가 없어도 심볼테이블을 통해
변수의 타입을 알아낸다는 의미가 되겠다.
하지만 만일 묵시적으로 선언된 변수가 외부에서 두가지 이상의 타입으로 선언되어 있다면 컴파일러가
어느 타입인지 추론하는게 어렵기 때문에 Link시 에러가 날 가능성이 있는 것이다.

많은 사람들이 extern 키워드를 이용하면 따로 변수를 선언하여 메모리를 잡는다고 이해하는 사람이 많다.
extern 키워드는 다른 파일에 선언되어 있는 변수를 링크시켜 자신이 만들고자 하는 프로그램에 쓸 수 있는 것이라
생각하면 된다. extern 키워드는 컴파일러에게

"이러한 변수가 어딘가에 선언되어 있고 그거 쓸꺼니까 메모리 올리지 말고 일단 그냥 넘어가~"
라는 말을 하는 것이다.

extern로 선언된 변수는 Link시에 심볼테이블을 검색을 통해 다른 obj들로 부터 찾게 된다.

다시 정리 하자!
extern 키워드를 사용해서 변수를 명시했다고 그것이 변수 선언을 의미하는게 아니다. 즉 메모리를 잡지 않는다는 것이다. 그 변수에 대한메모리는 다른 파일?에서 잡혀 있을거고, 링크타임때 그 변수에 대한 메모리를 찾아 링크시키는 것이다.
2008. 10. 3. 22:28

#pragma

#pragma 는 #로 시작하는 전처리구문 지시자 중 컴파일러에 종속적인 명령으로, 
컴파일러에 특정한 옵션 명령을 내리기 위해 사용하는 데요, 

컴파일러에 종속적이기 때문에 컴파일러를 변경했을 경우 실행을 보장하지 못합니다. 

대표적인 #pragma 명령 중에서 once나 pack, comment(lib, *) 등이 있는데 이는 각각 
컴파일러에 

1 once : 해당 소스가 단 한번만 포함되게 한다(여러 번 인클루드 되는 것을 
컴파일러 차원에서 막아줍니다) 

2 pack : 변수 정렬을 인위적으로 변경시킨다(보통은 4바이트로 지정되어 있습니다) 

3 comment(lib, *) : comment로 사용할 수 있는 명령은 여러 개 있는데, 
그중 가장 대표적인 것이 lib 으로, 해당 라이브러리를 링크시켜준다 

과 같은 명령을 내립니다. 



api나 mfc의 구분과 관계없이 해당 컴파일러에서 사용하는 명령이랍니다

 

 

 

MSDN에 있는 내용
code_seg
#pragma code_seg( ["section-name"[,"section-class"] ] )

Specifies a code section where functions are to be allocated. The code_seg pragma specifies the default section for functions. You can, optionally, specify the class as well as the section name. Using #pragma code_seg without a section-name string resets allocation to whatever it was when compilation began.

==========================================================

실행파일에는 코드영역과 데이터영역이 구분되어 있다는 것은 아시지요.
┌───────┐
│                     │
│                     │
│   데이터영역   │
│                     │
│                     │
├───────┤
│                     │
│                     │
│     코드 영역   │
│                     │
│                     │
└───────┘
이런 식의 그림은 아마 어디선가 많이 보셨을겁니다.(그림이 깨지네요.편집할 땐 제대로 보였는데...)
이런 영역을 section이라고 하지요. 위의 설명에 나오는 section이라는 용어가 이것입니다.
실제로 데이터 영역과 코드 영역외에도 exe나 dll에는 여러 section을 포함할 수 있습니다.
이건 dumpbin이라는 툴로 살펴볼 수 있습니다.
제 컴(Windows XP)에서 dumpbin c:\windows\notepadd.exe 를 해 보았더니

2000 .data
2000 .rsrc
7000 .text

이렇게 나오는 군요.

여기서 .data에는 초기화된 데이터가 .rsrc에는 리소스들이, .text에 코드가 들어갑니다.
이러한 .data, .rsrc, .text 등은 일반적으로 정해져 있는 것들입니다.
위 MSDN의 설명에 있는 section-name이라는 것이 바로 .data, .rsrc, .text 등을 뜻하는 겁니다.
즉, #pragma code_seg( .data ) 처럼 사용한다는 거지요.
그리고 Specifies a code section where functions are to be allocated.라는 설명은 
Specifies a section where functions or data or etc. are to be allocated. 이렇게 이해하면 더 나을 듯 하네요.

그런데 이런 정해진 이름말고도 사용자가 새로운 영역을 정할 수 있습니다.

#pragma data_seg("Shared")
DWORD g_dwThreadIdPMRestore = 0;
HWND g_hwnd = NULL;
#pragma data_seg()

이런 식으로 하면 g_dwThreadIdPMRestored와 g_hwnd가 디폴트 데이터 섹션인 .data에 배치되지 않고,
Shared라는 이름으로 만들어진 섹션에 배치되는 것입니다.

=====================================================

#pragma data_seg(...)가 사용되는 곳은 
dll간의 데이터 공유를 위해 사용될 수 있습니다.
그리고 그 외에 어디서 사용되는지는 저도 아직 본 적이 없어서 잘 모르겠습니다.

======================================================

참고로 위의 내용은 "어드밴스 윈도우 NT"를 참고해서 작성했습니다.
이 책은 지금 나오지 않고 이 책의 새 버전이 "Programming Applications for Microsoft Windows"(Jeffrey Richer 저)로
번역판도 나와 있습니다.


2008. 10. 3. 22:26

[펌] glibc, uClibc의 차이점

 

GNU C Library
http://www.gnu.org/software/libc/libc.html

 

GLIBC 는 GNU C Library 를 뜻합니다.

C언어 자체는 input/ouput , 메모리관리, 문자열 조작 등의 기능이 없습니다.

stdio.h 헤더 파일을 include 해야

printf 함수를 가지고 출력을 하고

scanf 함수를 가지고 입력을 받을 수 있습니다.

malloc , free 함수가 있어야 메모리 관리를 하고

strcmp, strcat 등의 함수가 있어야 문자열을 조작할 수가 있습니다.

이러한 것들을 할 수 있도록 도와주는 C library 중에

GNU 에서 제공하는 GLIBC 가 있는 것 입니다.

 

uClibc 는 작업환경이 일반 PC 보다 비교적 협소한 임베디드 환경에서 사용할 수 있도록

GLIBC 를 축소한 형태의 library 입니다.