C ++ 헤더 파일에 #ifndef 및 #define이 사용되는 이유는 무엇입니까?


496

헤더 파일의 시작 부분에서 다음과 같은 코드를 보았습니다.

#ifndef HEADERFILE_H
#define HEADERFILE_H

그리고 파일의 끝에는

#endif

이것의 목적은 무엇입니까?


36
+1-나도 의심이 많았으며 여기에 훨씬 더 좋은 대답을 얻었으며 향후 방문객에게 유용 할 수 있습니다 : stackoverflow.com/q/3246803/1134940
— Abid Rahman K

6
#pragma를 한 번 사용할 수 있다는 것을 덧붙이고 싶습니다. 이것이 당신이해야 할 전부이며 ifndef와 동일한 목적을 제공합니다. 이 두 가지를 비교하려면 다음을 참조하십시오. stackoverflow.com/questions/1143936/…
— Dimension

3
a #pragma가 무엇인지 언급하는 것이 가장 좋습니다 : 컴파일러 관련 기능을 활성화합니다. 하지만 #pragma once되어 매우 광범위하게 지원, 그것은 비표준입니다.
— Potatoswatter 2016 년

3
@Dimension : GNU의 자체 문서 ( info cpp또는 여기 참조 )는 "모든 전 처리기에서 인식되지 않으므로 휴대용 프로그램에서이를 사용할 수 없습니다"라고 말합니다. 그리고 GNU cpp는 일반 및 휴대용 #ifndef관용구를 최적화하여 만큼 효율적 #pragma once입니다.
— Keith Thompson

3
고려해야 할 사항 : 밑줄로 시작하는 매크로 이름을 사용하지 마십시오. 이러한 식별자는 구현에 예약되어 있습니다. 더 미묘하게도 #ifndef HEADERFILE_H헤더 이름의 구현 네임 스페이스를 위반할 수 있습니다 E. 로 시작하는 식별자와 E숫자 또는 대문자는에 예약되어 <errno.h>있습니다. 나는 제안한다 #ifndef H_HEADERFILE.
— 키이스 톰슨

답변:


526

이를 #include guards 라고 합니다.

헤더가 포함되면 고유 한 값 (이 경우 HEADERFILE_H)이 정의 되어 있는지 확인합니다 . 정의되지 않은 경우이를 정의하고 나머지 페이지로 계속 진행합니다.

코드가 다시 포함되면 첫 번째 코드가 ifndef실패하여 빈 파일이 생성됩니다.

유형, 열거 형 및 정적 변수와 같은 식별자의 이중 선언을 방지합니다.


1
Koning Baard XIV : VC도 #pragma once같은 작업을 수행합니다. –)
— Joey

95
또한 재귀 적 포함을 방지합니다. "alice.h"에 "bob.h"가 포함되어 있고 "bob.h"에 "alice.h"가 포함되어 있고 경비원이 포함되어 있지 않다고 상상해보십시오.
— Kevin Dungs

@ 케빈 : 그게 내가 의미하는 바입니다. 조작 할 양식에 의해 열린 양식을 조작하고 싶었습니다. 그것은 많은 오류를줬고 어떻게 해야할지 몰랐습니다. 내가 포기했다 =)

6
@ Јοеу : #pragma once휴대용이 아닙니다. 일반적인 #ifndef관용구가 권장됩니다.
— Keith Thompson

2
@CIsForCookies 자주 사용하는 검색 엔진에 "하나의 정의 규칙"을 입력하십시오.
— David Schwartz

33
#ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif

#ifndef주어진 토큰이 #defined파일 또는 포함 된 파일의 이전에 있는지 확인합니다 . 그렇지 않은 경우에는 코드와 닫는 사이의 코드 #else또는 #else존재 하지 않는 경우 #endif명령문이 포함됩니다. #ifndef파일이 포함되면 토큰을 정의하고 해당 파일의 맨 위에 토큰이 설정되지 않았는지 확인하여 헤더 파일을 dem 등원으로 만드는 데 종종 사용됩니다.

#ifndef _INCL_GUARD
#define _INCL_GUARD
#endif

4
밑줄로 시작하는 식별자는 예약되어 있습니다. 직접 정의해서는 안됩니다. 같은 것을 사용하십시오 #ifndef H_HEADER_NAME.
— Keith Thompson

5
나는 이것이 오래된 주석이라는 것을 알고 있지만 실제로 밑줄 제한은 "외부 식별자"에만 적용됩니다-식별자는 컴파일 된 객체의 심볼 테이블, 즉 전역 변수 및 함수 이름으로 끝날 수 있습니다. 매크로 이름에는 적용되지 않습니다.
— Stu

1
Stu의 의견이 사실입니까? 방금 stackoverflow.com/questions/228783/…을 읽었 으며 지금은 확실하지 않습니다.
— 윌

9

이렇게하면 동일한 헤더 파일이 여러 번 포함되지 않습니다.

#ifndef __COMMON_H__
#define __COMMON_H__
//header file content
#endif

이 헤더 파일을 여러 파일에 포함했다고 가정하십시오. 따라서 __COMMON_H__이 처음 정의되지 않으면 정의되고 헤더 파일이 포함됩니다.

다음에 __COMMON_H__이 정의되었으므로 다시 포함되지 않습니다.


1

그것들을 ifdef라고 부르거나 가드를 포함합니다.

작은 프로그램을 작성하는 경우 필요하지 않은 것 같지만 프로젝트가 커짐에 따라 의도적으로 또는 실수로 한 파일을 여러 번 포함 할 수 있으므로 이미 선언 된 변수와 같은 컴파일 경고가 발생할 수 있습니다.

#ifndef checks whether HEADERFILE_H is not declared.
#define will declare HEADERFILE_H once #ifndef generates true.
#endif is to know the scope of #ifndef i.e end of #ifndef

선언되지 않은 경우 #ifndef가 true를 생성하면 #ifndef와 #endif 사이의 부분 만 그렇지 않으면 실행되지 않습니다. 이렇게하면 식별자, 열거 형, 구조 등을 다시 선언하지 못하게됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.