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.