반응형

리눅스/윈도우 C : 헤더파일 중복 참조 방지

알게된 배경

 참여하는 프로젝트에서 소켓 네트워크 프로그램을 만들어야 하는데, 가장 먼저 잡은 책이 하필 C로 실습하는 책이었다. 문제는 C는 운영체제를 많이 타는 편이라서 리눅스와 윈도우를 같이 번갈아가면서 사용해야 했다.


들어가기에 앞서

 현재 C도 C++처럼 표준이 존재하며, 리눅스는 C90 ~ C99를 지원하고, 윈도우는 C80만 지원한다. 따라서 지속적으로 계속 차이가 날 수 밖에 없다. 그리고 대부분의 C 학습 서적은 대부분 윈도우 환경의 Microsoft Visual(MV) C++ 컴파일러를 기준으로 되어 있다.


매크로변수로 구분하는 방법(#ifndef)

예시)

#ifndef _HEADER_H_
#define _HEADER_H_

int func1(void);

#endif //_HEADER_H_

초기 C에서 사용되는 방법으로 매크로 변수 선언여부에 따라서 컴파일러는 정해진 구간의 코드를 컴파일하지 않는다. 매크로는 컴파일 하기전에 실행되는 것이기 때문에 이를 통해서 매번 다른 C파일에서 중복으로 헤더파일을 인클루드 해도 컴파일러는 여러번 참조하지 않는다. 헤더파일 중복 참조를 막기 위한 변수명은 위의 코드처럼 _(언더바)로 시작하고 대문자로 작성하며, 마지막에 _H_로 표기하도록 권장한다.


 다만, 기기 입장에서 컴파일을 할때 매크로에 의해서 컴파일전에 헤더파일의 내용을 건너뛰기는 하지만, 파일 전체가 아닌 구간을 넘기는 거라서 원리상 파일을 중복 참조하기는 한다. 그렇지만, 이게 워낙 빨라서 사람이 체감하기는 어렵다.


한번만 읽는 매크로를 실행하는 방법(#pragma once)

#pragma once

int func1(void);

MV C++ 에서 사용하기 시작한 방법이다. 매크로는 컴파일러가 컴파일전에 작업한다는 것을 다시 한번 상기하자. 매크로 명령어로 컴파일러에게 컴파일전에 이 파일은 한번만 읽으라고 하는 의미이다. 결국 앞의 매크로변수 유무에 따라서 컴파일하는 것과 같은 결과를 갖게 되는데, 원리상 차이가 있다.


 파일을 한번만 읽으라고 했기 때문에 아무래도 매크로 변수 존재 유무를 확인하고 구간을 건너뛰는 것보다는 매크로실행과정이 짧아진다. 물론 속도 차이는 체감이 거의 안된다.


중복참조 선택방법

 이러한 매크로(#pragma once)는 처음에 MV C++에서만 지원이 되었고 비표준이었다. 하지만, 요즘에는 표준화가 되었다. 그러나 아직 표준화 된지 오래 안되어서 인지 지원이 안되는 컴파일러가 있을 수 있기에 아직도 매크로 변수를 이용한 중복 참조를 피하는 방법을 리눅스 프로그래밍(OS X 에서도) 쪽에서는 아직도 많이 사용하고 있다.


 자신의 개발환경이 오래된 혹은 가벼운 컴파일러를 사용해야 할 경우에는 어쩔 수 없이 매크로변수를 이용해야 하고 그게 아니라면 #pragma once를 사용하자.


위키피디아에서 #pragma once 매크로가 지원되는 컴파일러 목록이 정리되어 있다

[참조링크]


반응형

+ Recent posts