#pragma는 한 번 C ++ 11 표준의 일부입니까?


140

전통적으로 C ++에 여러 헤더가 포함되는 것을 피하는 표준 및 이식 가능한 방법은 매크로 가드 체계#ifndef - #define - #endif 라고도 하는 프리 컴파일러 지시문 체계 를 사용하는 것입니다 (아래 코드 조각 참조).

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

그러나 대부분의 구현 / 컴파일러 (아래 그림 참조)에는라는 매크로 보호 체계와 동일한 목적을 수행하는보다 "우아한"대안이 있습니다 #pragma once. #pragma once코드 보호, 이름 충돌 방지, 때로는 컴파일 속도 향상을 포함하여 매크로 가드 체계와 비교하여 몇 가지 장점이 있습니다.

여기에 이미지 설명을 입력하십시오

몇 가지 연구를 통해 #pragma once지시문이 거의 모든 알려진 컴파일러에서 지원 되지만 지시문이 #pragma onceC ++ 11 표준의 일부 인지 여부에 대한 혼돈이 있음을 깨달았습니다 .

질문 :

  • #pragma once지시문이 C ++ 11 표준의 일부 인지 여부를 누군가가 명확히 할 수 있습니까?
  • C ++ 11 표준의 일부가 아닌 경우 이후 릴리스 (예 : C ++ 14 이상)에 포함시킬 계획이 있습니까?
  • 누군가가 기술 중 하나를 사용할 때의 장점 / 단점에 대해 더 자세히 설명 할 수 있다면 좋을 것입니다 (예 : 매크로 가드 대 #pragma once).

9
또한, 헤더 가드에 이중 밑줄을 사용하는 것은 표준에 의해 금지되어 있으며, 이중 밑줄로 시작하는 모든 기호 (기타 포함)를 구현합니다.
Matteo Italia

9
밑줄과 대문자를 사용하는 것도 금지됩니다. 둘째, 탁도는 어디에 있습니까? 컴파일러 지원 만 보았습니다. 표준의 일부라고 주장하는 사람은 아무도 없습니다.
Yakk-Adam Nevraumont

1
세 번째 글 머리표를 보려면 관련 질문을 살펴보십시오. #pragma가 안전한 포함 가드입니까? 헤더 가드가 작동하지만 #pragma once일반적으로 작동하지 않는 상황이 있습니다.
user1942027

1
C ++ 11을 언급하지 않고이 질문에 대답한다는 점에서 가능한 중복 .
Yakk-Adam Nevraumont

3
글쎄, 공식 문서에는 코드화되어 있지 않지만 사실상 표준 으로 간주 할 수 있습니다 .
Siyuan Ren

답변:


107

#pragma once표준 이 아닙니다 . 널리 사용되는 것은 아니지만 널리 사용되는 확장입니다.

  • 휴대 성 문제가 제한적인 경우
  • 모든 포함 파일이 항상 로컬 디스크에 있는지 확인할 수 있습니다.

표준화를 위해 고려되었지만 신뢰성있게 구현할 수 없기 때문에 거부되었습니다. 여러 다른 원격 마운트를 통해 파일에 액세스 할 수있는 경우 문제가 발생합니다.

단일 개발 내에서 포함 가드 충돌이 없는지 확인하는 것은 매우 쉽습니다. 많은 다른 개발에서 사용될 수있는 라이브러리의 경우 확실한 해결책은 포함 가드를 작성할 때 무작위 문자를 많이 생성하는 것입니다. (새 헤더를 열 때마다이 작업을 수행 할 수있는 좋은 편집기를 설정할 수 있습니다.) 그러나이 기능이 없어도 라이브러리 간 충돌 문제는 아직 발생하지 않았습니다.


11
원격 마운트 만이 아닙니다. 하드 링크, 소프트 링크, 서브스 트럭 트 구조 (Windows). 정말 지저분해질 수 있습니다.
Tonny

45
컴파일러에서 파일을 식별하기 위해 SHA-1 또는 MD5 체크섬을 사용할 수없는 이유는 무엇입니까?
Sergey

29
모든 주요 컴파일러가 지원한다면 표준에 무언가를 넣지 않는 것이 중요하지 않습니다. 실제로 표준보다 이것보다 훨씬 덜 지원되는 것들이 있습니다. 또한 파일 이름 충돌이 이미 큰 문제인 포함 파일에 대해 이야기 할 때 가장자리 문제에 대해 불평하는 것은 꽤 어리석은 것처럼 보입니다. 100 % 문제가없는 기능에 대한 이러한 요구가 일반적으로 #included 헤더 파일의 개념에 적용된다면 좋을 것입니다.
TED

38
코드에 심볼릭 링크 또는 이상한 마운트를 통해 다른 위치의 파일이 포함되어 있으면 이미 이식 가능하지 않습니다. 따라서 pragma once본질적으로 이식 가능하지 않으며 (고려해서는 안되는) 것을 이식 가능하게 구현할 수 없다고 주장하는 것은 C ++ 거꾸로 된 세계의 또 다른 넌센스입니다.
doc

7
@JoseAntonioDuraOlmos 나는 심볼릭 링크가 C ++ 언어의 범위를 벗어난 OS 기능이라는 것에 동의합니다. 따라서 C ++ comitee가 언어 범위를 벗어난 것을 고려해야하는 이유는 무엇입니까? 자신의 책임이 아닌 것을 보장하려고 시도하는 것은 IMO에 의미가 없습니다. DOS는 파일 이름 당 8 + 3 개의 문자 만 지원했지만 #include맹목적으로 맹목적으로 잘못 사용할 수 있기 때문에 제거해야 할 주장은 없습니다 . #pragma once어떤 식 으로든 이식성을 제한하지 않으며 컴파일을 중단하기 위해 기호 링크를 이용하지 않습니다.
doc

32

표준의 §16.6 ( N3936 초안)은 #pragma지침을 다음과 같이 설명 합니다.

양식의 전처리 지시문

# pragma pp-tokensopt new-line

구현이 구현 정의 방식으로 작동하도록합니다. 이 동작으로 인해 번역이 실패하거나 번역기 또는 결과 프로그램이 부적합한 방식으로 작동 할 수 있습니다. 구현에서 인식되지 않는 pragma는 무시됩니다.

기본적으로 지시문 #pragma once의 구현 별 인스턴스이며 #pragma표준이 아닙니다. 아직.

GCCClang을 포함한 대부분의 "주요 컴파일러"에서 널리 지원 되므로 include-guards 상용구를 피하는 것이 좋습니다.


10
헤더 가드 #pragma와 둘 다 사용할 수 있습니다 #define.
Yakk-Adam Nevraumont

18
"구현으로 인식되지 않는 pragma는 무시 됩니다. " 경고 : 인식 할 수없는 pragma 지시문 이 적합하지 않은 메시지 입니까?
rodrigo

6
"따라서 include-guards 상용구를 피하기 위해 권장되는 방법"-매우 대담한 진술입니다. 비표준 방식이며 사용의 이점은 거의 없으며 내 경험과 관련이 거의 없으므로 +1을 빼야했습니다.
Alex

19
@ Yakk : 누군가 #define헤더 가드를 작성한다면 , 그럴 이유 #pragma once도 없습니다.
Nawaz

5
@Nawaz 컴파일러는 #pragma onced 가 된 모든 파일의 캐시를 (경로별로) 유지할 수 있으며 #include다시 d 가 발생 하면 #include(파일을 열지 않아도) 건너 뛸 수 있습니다 . gcc는 헤더 가드와 동일 하지만 매우 취약합니다. #pragma사람이 쉽게 할 헤더 가드 하나는 어렵다.
Yakk-Adam Nevraumont
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.