위의 코드는 macro wrapper 방식을 이용해서 중복 include를 제거하는 것이고, 아래는 #pragma directive로 처리기에 직접 지시하는 방법의 차이가 있습니다.
위의 방법은 #ifndef 매크로 처리기를 통해 특정 매크로가 선언되어 있으면 조건이 참이 아니므로 #endif 까지의 코드가 무효화됩니다.
#pragma once는 컴파일러 (정확히는 preprocessor겠지요)에게 이 파일은 한번만 읽어들이라고 지시하는 것으로, 효과는 위와 동일하겠지요.
하지만, 매크로 래퍼 방식은 전처리기가 파일을 계속 읽어서 위의 #ifndef 문을 비교해봐야 합니다. 즉 #include "xxx.h"를 발견할 때마다 xxx.h 파일을 스캔해야 하지요.
#pragma once를 사용하면 컴파일러가 xxx.h는 한번만 읽으면 된다는 것을 알기 때문에 파일을 리스캔할 필요가 없습니다.
후자가 표준인지 아닌지는 정확히는 모르지만, GCC 및 VC++ 둘 다 잘 됩니다.
ps) K&R CPP 매뉴얼에는 몇몇 third party 프리프로세서들은 #pragma once를 이해할 수 없을 수도 있다고 나오네요.
ps2) GCC CPP 매뉴얼을 보니, 이제는 꼭 #pragma once를 안써주고 #ifndef 스타일로 헤더를 작성해도 CPP가 기억하는 기능이 추가된 모양입니다~
ps3) 여기서 CPP는 C++가 아니라 C PreProcessor를 나타냅니다 :lol:
좀 오해의 소지가 있어서 부연하면 #pragma 자체는 표준에서 정의된 전처리
지시어가 맞습니다. 하지만 그 뒤에 붙는 것들은 컴파일러마다 알아서 정의하도록
되어 있습니다. 따라서 #pragma 지시어는 이식성이 없다고 볼 수 있는 거죠.
MSVC++에서 #pragma once를 쓰면 한 번 #include 된 파일은 다시 열지
않도록 한다는군요. 그래서 컴파일 시간을 줄일 수 있답니다.
include guard는 일단 파일을 열어서 읽어보기는 해야 하니 조금은 시간이 더
걸리긴 하겠습니다만, 그 시간이 문제가 되었던 적은 없었고 include guard로도
충분히 원하는 것을 할 수 있었습니다.
개인적으로는 이식성 없는 #pragma once를 쓰기보다는 차라리 파일 의존성을
줄이는 쪽으로 소스를 작성하는 편이 훨씬 낫다고 봅니다.
뭐, 다들 아시겠지만 '표준'이라고 다 통하는 건 아닙니다. 아직까지 GCC 3.x에서조차 C99가 fully impliment된 상황이 아니거든요. 그래서 아래 pragma는 표준에서 이렇게 하자고 제안한 것일 뿐입니다. 널리 쓰이는 표준(de facto standard)은 아직까지는 C89~C90으로 봐야겠죠.
cinsk wrote:
예전에는 #pragma로 시작하는 directive들은 모두 컴파일러에 의존적인 사항이었지만 #pragma STD ... 로 시작하는 것은 표준입니다.
원 질문에 대한 답은 vacancy님이 맞습니다.
표준(C99) #pragma는 현재 다음 세가지가 있습니다:
#pragma STDC FP_CONTRACT on-off
#pragma STDC FENV_ACCESS on-off
#pragma STDC CX_LIMITED_RANGE on-off
on-off := ON | OFF | DEFAULT
후자는 표준이 아닙니다.( .. 내지는 아니었습니다. 현재는 모르
후자는 표준이 아닙니다.
( .. 내지는 아니었습니다. 현재는 모르겠네요. )
Re: #ifndef... 와 #pragma once의 차이점이 뭔가요?
위의 코드는 macro wrapper 방식을 이용해서 중복 include를 제거하는 것이고, 아래는 #pragma directive로 처리기에 직접 지시하는 방법의 차이가 있습니다.
위의 방법은 #ifndef 매크로 처리기를 통해 특정 매크로가 선언되어 있으면 조건이 참이 아니므로 #endif 까지의 코드가 무효화됩니다.
#pragma once는 컴파일러 (정확히는 preprocessor겠지요)에게 이 파일은 한번만 읽어들이라고 지시하는 것으로, 효과는 위와 동일하겠지요.
하지만, 매크로 래퍼 방식은 전처리기가 파일을 계속 읽어서 위의 #ifndef 문을 비교해봐야 합니다. 즉 #include "xxx.h"를 발견할 때마다 xxx.h 파일을 스캔해야 하지요.
#pragma once를 사용하면 컴파일러가 xxx.h는 한번만 읽으면 된다는 것을 알기 때문에 파일을 리스캔할 필요가 없습니다.
후자가 표준인지 아닌지는 정확히는 모르지만, GCC 및 VC++ 둘 다 잘 됩니다.
ps) K&R CPP 매뉴얼에는 몇몇 third party 프리프로세서들은 #pragma once를 이해할 수 없을 수도 있다고 나오네요.
ps2) GCC CPP 매뉴얼을 보니, 이제는 꼭 #pragma once를 안써주고 #ifndef 스타일로 헤더를 작성해도 CPP가 기억하는 기능이 추가된 모양입니다~
ps3) 여기서 CPP는 C++가 아니라 C PreProcessor를 나타냅니다 :lol:
...
좀 오해의 소지가 있어서 부연하면 #pragma 자체는 표준에서 정의된
좀 오해의 소지가 있어서 부연하면 #pragma 자체는 표준에서 정의된 전처리
지시어가 맞습니다. 하지만 그 뒤에 붙는 것들은 컴파일러마다 알아서 정의하도록
되어 있습니다. 따라서 #pragma 지시어는 이식성이 없다고 볼 수 있는 거죠.
MSVC++에서 #pragma once를 쓰면 한 번 #include 된 파일은 다시 열지
않도록 한다는군요. 그래서 컴파일 시간을 줄일 수 있답니다.
include guard는 일단 파일을 열어서 읽어보기는 해야 하니 조금은 시간이 더
걸리긴 하겠습니다만, 그 시간이 문제가 되었던 적은 없었고 include guard로도
충분히 원하는 것을 할 수 있었습니다.
개인적으로는 이식성 없는 #pragma once를 쓰기보다는 차라리 파일 의존성을
줄이는 쪽으로 소스를 작성하는 편이 훨씬 낫다고 봅니다.
답변 감사 드립니다.
감사합니다.
저녁 맛나게 드세요 :lol:
삶을위한플밍...
예전에는 #pragma로 시작하는 directive들은 모두 컴파일러에
예전에는 #pragma로 시작하는 directive들은 모두 컴파일러에 의존적인 사항이었지만 #pragma STD ... 로 시작하는 것은 표준입니다.
원 질문에 대한 답은 vacancy님이 맞습니다.
표준(C99) #pragma는 현재 다음 세가지가 있습니다:
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
뭐, 다들 아시겠지만 '표준'이라고 다 통하는 건 아닙니다. 아직까지 G
뭐, 다들 아시겠지만 '표준'이라고 다 통하는 건 아닙니다. 아직까지 GCC 3.x에서조차 C99가 fully impliment된 상황이 아니거든요. 그래서 아래 pragma는 표준에서 이렇게 하자고 제안한 것일 뿐입니다. 널리 쓰이는 표준(de facto standard)은 아직까지는 C89~C90으로 봐야겠죠.
댓글 달기