#ifndef... 와 #pragma once의 차이점이 뭔가요?

khy2happy의 이미지

#ifndef  ABC_H
#define ABC_H

.....
class CABC
{
.....
}; 

#endif

#pragma once
....
class CABC
{
}

두개의 차이점이 뭔가요?
비슷한거 같은데 사용할때 보면 똑같지는 않은거 같고.
MSDN을 읽어봐도 영어가 짧아서 이해가 잘 안돼네요.
:D 좋은하루 되세요. :D

vacancy의 이미지

후자는 표준이 아닙니다.

( .. 내지는 아니었습니다. 현재는 모르겠네요. )

leigh의 이미지

#ifndef  ABC_H
#define ABC_H

.....
class CABC
{
.....
}; 

#endif

#pragma once
....
class CABC
{
}

위의 코드는 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:

...

doldori의 이미지

좀 오해의 소지가 있어서 부연하면 #pragma 자체는 표준에서 정의된 전처리
지시어가 맞습니다. 하지만 그 뒤에 붙는 것들은 컴파일러마다 알아서 정의하도록
되어 있습니다. 따라서 #pragma 지시어는 이식성이 없다고 볼 수 있는 거죠.
MSVC++에서 #pragma once를 쓰면 한 번 #include 된 파일은 다시 열지
않도록 한다는군요. 그래서 컴파일 시간을 줄일 수 있답니다.
include guard는 일단 파일을 열어서 읽어보기는 해야 하니 조금은 시간이 더
걸리긴 하겠습니다만, 그 시간이 문제가 되었던 적은 없었고 include guard로도
충분히 원하는 것을 할 수 있었습니다.
개인적으로는 이식성 없는 #pragma once를 쓰기보다는 차라리 파일 의존성을
줄이는 쪽으로 소스를 작성하는 편이 훨씬 낫다고 봅니다.

khy2happy의 이미지

감사합니다.
저녁 맛나게 드세요 :lol:

삶을위한플밍...

cinsk의 이미지

예전에는 #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
terzeron의 이미지

뭐, 다들 아시겠지만 '표준'이라고 다 통하는 건 아닙니다. 아직까지 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

댓글 달기

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