#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표준이 아닙니다. 아직.

GCC 및 Clang을 포함한 대부분의 "주요 컴파일러"에서 널리 지원 되므로 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.