경비원을 포함하다

include guard

CC++ 프로그래밍 언어에서 #include guard매크로 가드, 헤더 가드 또는 파일 가드라고도 불리며 include 디렉티브를 처리할 때 이중 포함 문제를 피하기 위해 사용되는 특별한 구성입니다.

C 프리프로세서는 폼의 디렉티브를 처리합니다.#include <file>소스 파일에서 관련 파일을 찾습니다.file 내용을 변환 유닛이라고 하는 소스 파일의 카피로 변환해, 프로세스의 include 디렉티브를 치환합니다.이와 관련하여 포함된 파일은 일반적으로 헤더 파일이며, 여기에는 일반적으로 함수 및 클래스 또는 구조 선언이 포함됩니다.특정 C 또는 C++ 언어구조를 두 번 정의하면 변환단위는 비활성화됩니다.#이중포함 메커니즘에 의해 이러한 잘못된 구조가 발생하는 것을 방지합니다.

헤더 파일에 #include guards를 추가하는 것도 해당 파일을 유휴 상태로 만드는 한 가지 방법입니다.이중 포함에 대처하기 위한 또 다른 구조는 #pragma once입니다.이것은 비표준이지만 C와 C++ 컴파일러 사이에서 거의 보편적으로 지원됩니다.

이중포함

다음 C 코드는 #include guards가 누락된 경우 발생할 수 있는 실제 문제를 보여줍니다.

파일 "grandparent"h"

구조 후우 {     인트 멤버; }; 

파일 "parent" (부모)h"

#실패하다 "투명합니다.h" 

파일 "child".c"

#실패하다 "투명합니다.h" #실패하다 "부모님.h" 

결과

구조 후우 {     인트 멤버; }; 구조 후우 {     인트 멤버; }; 

여기서 파일 "child.c"는 헤더 파일 "grandparent"에 텍스트의 두 복사본을 간접적으로 포함합니다.h". 이것은 컴파일 오류를 일으킵니다.구조체 타입이foo따라서 두 번 정의됩니다.C++ 에서는, 이것을 1 개의 정의 룰의 위반이라고 부릅니다.

#가드 포함

이 섹션에서는 #include guards를 추가하여 동일한 코드를 사용합니다.C 프리프로세서는 헤더파일을 전처리합니다.또한 헤더파일을 재귀적으로 전처리합니다.이렇게 하면 올바른 소스 파일이 생성됩니다.

파일 "grandparent"h"

#조부모_H #할아버지 정의_H  구조 후우 {     인트 멤버; };  #엔디프/* GRANGENTH 

파일 "parent" (부모)h"

#실패하다 "투명합니다.h" 

파일 "child".c"

#실패하다 "투명합니다.h" #실패하다 "부모님.h" 

결과

구조 후우 {     인트 멤버; }; 

여기, "할아버지"의 첫 번째 포함입니다.h"는 매크로를 가진다.GRANDPARENT_H정의되어 있습니다.child.c에 grandparent가 포함되어 있는 경우.두 번째 시간에는 h"로 표시됩니다.#ifndeftest는 false를 반환하고 preprocessor는 아래쪽으로 건너뜁니다.#endif그 때문에, 의 2번째 정의를 회피합니다.struct foo프로그램이 올바르게 컴파일 됩니다.

논의

가드 매크로에 대한 다른 명명 규칙은 다른 프로그래머에 의해 사용될 수 있습니다.위의 예의 다른 일반적인 형식은 다음과 같습니다.GRANDPARENT_INCLUDED,CREATORSNAME_YYYYMMDD_HHMMSS(적절한 시간 정보를 대체하여) 및 UUID에서 생성된 이름(단, 하나의 밑줄로 시작하는 이름, 대문자로 시작하는 이름 또는 이중 밑줄을 포함하는 이름, 예를 들어 다음과 같습니다._GRANDPARENT__H그리고.__GRANDPARENT_H는 언어 실장용으로 예약되어 있으며 사용자가 사용할 수 없습니다.)[1][2]

물론 동일한 include-guard 매크로 이름을 다른 헤더 파일에 중복시키지 않도록 하는 것이 중요합니다.첫 번째를 포함하면 두 번째 헤더에 포함된 선언, 인라인 정의 또는 기타 #가 손실되기 때문입니다.

애로

#include guards가 정상적으로 동작하려면 각 가드가 다른 프리프로세서 매크로를 테스트하고 조건부로 설정해야 합니다.따라서 #include guards를 사용하는 프로젝트에서는 include guards에 대해 일관성 있는 이름 지정 체계를 작성하고 사용하는 서드파티 헤더 또는 글로벌하게 표시되는 매크로 이름과 충돌하지 않도록 해야 합니다.

이 때문에, 대부분의 C 및 C++ 실장에서는, 비표준이 됩니다.#pragma once지시.헤더 파일의 맨 위에 삽입된 이 지시어는 파일이 한 번만 포함되도록 합니다.Objective-C 언어(C의 슈퍼셋)는 다음과 같은 기능을 도입했습니다.#importdirectional, 즉 명령어와 동일하게 동작합니다.#include단, 각 파일은 1회만 포함되므로 #syslog [3]guards가 필요하지 않습니다.

기타 언어

PL/I는%INCLUDEC에 상당하는 진술#include지시.IBM Enterprise PL/I는 또한%XINCLUDE"외부 텍스트가 이전에 포함되지 않은 경우 소스 프로그램으로 변환됩니다."이것은 C와 다르다.#pragma once외부 텍스트를 포함하는 프로그램이 포함된 텍스트 자체가 아니라 중복 텍스트를 포함하지 않도록 지정하는 역할을 합니다.

또,XPROCEDURE스테이트먼트(와 유사)PROCEDURE두 번째 이후의 발생은 무시됩니다.XPROCEDURE같은 [4]이름의

「 」를 참조해 주세요.

레퍼런스

  1. ^ C++ 표준 (ISO/IEC 14882)섹션 17.4.3.1.2/1
  2. ^ C 표준(ISO/IEC 9899) 섹션 7.1.3/1.
  3. ^ "Objective C: Defining Classes". developer.apple.com. 2014-09-17. Retrieved 2018-10-03.
  4. ^ IBM Corporation (August 2017). Enterprise PL/I for z/OS PL/I for AIX Enterprise PL/I for z/OS Language Reference Version 5 Release 1 (PDF). p. 257. Retrieved Apr 7, 2022.

외부 링크