2011-02-01 2 views
16

C++에는 일반적으로 이름이 지정된 경비원이 어떻게 포함됩니까? 나는 이것을 많이 보는 경향이 있습니다 :이름 붙이기 가드

#ifndef FOO_H 
#define FOO_H 

// ... 

#endif 

그러나 저는 그것이 매우 직관적이라고 생각하지 않습니다. 파일 이름을 보지 않고는 FOO_H이 무엇인지, 그 이름이 무엇을 의미하는지 알려주지 않습니다.

가장 좋은 방법은 무엇입니까?

+2

이름이 다소 직관적 수 있지만, 사실에 있다는 것입니다 약간의 경험을하면 그 라인을 읽지 않습니다. 눈과 두뇌는'#ifdef blahblah ... '에 익숙해지며 실제로 검사중인 내용을 읽지는 않습니다. 포함 감시입니다. –

+3

이것에 대한 다소 유용한 견해 : http://stackoverflow.com/questions/1744144/adding-an-include-guard-breaks-the-build/1744302#1744302 –

+0

C++ 개발을하는 사람은 누구나 헤더 가드 인식에 익숙해 져야합니다. 매우 빠르게. 당신이보고있는 표준을 항상 따라갈 것입니다. "최상의"방법 (따옴표로 묶어야 함)은 ifndef를 먼저 쓰고, 바로 뒤에 정의하고, 파일의 끝에서 끝내는 것입니다. 나는 당신이 이것을 깨달을 것을 배우는 것이 좋습니다. –

답변

15

필자 자신의 경험에 비추어 볼 때 관례는 이름이 모두 대문자이고 마침표가 밑줄로 대체된다는 것을 제외하고는 포함 된 헤더 파일 다음에 포함 가드 이름을 지정하는 것입니다.

따라서 test.hTEST_H이됩니다.

실제 사례로는 클래스 헤더 파일을 자동 생성 할 때이 규칙을 따르는 Qt Creator가 있습니다.

+4

모든 프로젝트의 모든 파일과 서브 디렉토리가없는 동일한 디렉토리의 모든 라이브러리를 유지하기 때문에 FILENAME_H를 포함 보호 이름으로 사용하는 것이 좋습니다. 따라서 파일 이름이 충돌하지 않는다는 것을 알 수 있습니다 ... –

+2

이것은 일반적인 관행입니다 #define과 다른 이름으로 상점이하는 일에 따라 충분하지 않을 수도 있습니다. –

1

나는 보통 FOO_H_INCLUDED_과 같은 것을 사용합니다. 몇 가지 (Microsoft) 헤더는 GUID의 문자열 표현과 비슷하지만 정교한 것은 필요하지 않습니다.

3

FOO_HFOO_H_INCLUDED으로 바꾸십시오.

1

일반적으로 사람들은 파일 이름별로 파일을 작성하므로 각 파일의 코드는 한 번만 컴파일되고 추가됩니다. FOO_H를 원하는대로 만들 수 있지만, 코딩하거나 본 모든 것이 파일 이름을 사용했습니다. 다른 사람의 FOO_H와 (과) 충돌하는 FOO_H를 원하지 않기 때문에 고유한지 확인하십시오.

10

google's style guide에서 직접 촬영 :

모든 헤더 파일은 다중 포함을 방지하기 위해 #DEFINE 경비원이 있어야합니다. 심볼 이름의 형식은 이어야합니다. < 프로젝트> _ < 경로> _ < FILE> _H_. 은 고유성을 보장하기 위해 프로젝트 소스 트리의 전체 경로를 기반으로 이어야합니다.

#ifndef FOO_BAR_BAZ_H_ 
#define FOO_BAR_BAZ_H_ 
... 
#endif // FOO_BAR_BAZ_H_ 

난 내 자신의 프로젝트에이 스타일을 사용하는 예를 들어, 프로젝트 foo는 에서 파일 foo는/SRC/바/baz.h는 다음과 같은 가드가 있어야합니다.

+5

Google 코딩 표준은 일반적으로 말하면 내가 본 중 가장 나쁜 것 중 하나이지만 네임 스페이스가있는 접두사입니다. 여러 네임 스페이스에서 같은 이름을 가진 것이 있다면 꼭 필요합니다. –

+0

내가 알아 내려고 노력했지만, 밑줄 뒤에 어떤 추론이 있습니까? – Toby

+1

@ 토비 그냥 (더) 독특한 만들 ...누군가가 이미'CONFIG_H '를 가지고 있다면 (예를 들면 포함 된 라이브러리와 같이)'CONFIG_H_'를 사용하면 충돌하지 않습니다. 어떤 사람들은 밑줄을 쓴 것과 같은 이유가 있지만, thags가 예약 했으므로해서는 안됩니다. – RastaJedi

1

나는 보통 몇 시간 만보고 그 말미에 덧붙입니다. 즉, FOO_H_248입니다. 여분의 예방책이므로 어쨌든 기억하지 않아도됩니다. 따라서 걱정할 필요가 없습니다. 그건 사실이 아니야. 다른 사람이 전에 언급 한 바와 같이

+0

12시 또는 24 시간 시계를 사용하고 있으며 현지 시간입니까? ;-) – T33C

+5

@ T33C : 12? 24? 너 무슨 소리 야? 그것은 단지 17 시간 시계입니다. 그리고 그 순간 교황이있는 곳이면 누구나 현지 시간입니다. –

2

은 매우 일반적인 규칙은 밑줄로 대체 이름의 대문자 버전, 도트를 사용하는 것입니다 : foo.h -> FOO_H

그러나이와 이름 충돌로 이어질 수 단순 및/또는 일반적인 이름.

#ifndef FOO_H__NsknZfLkajnTFBpHIhKS 
#define FOO_H__NsknZfLkajnTFBpHIhKS 
#endif 

http://www.random.org/strings/이 유용한 임의 생성기입니다 : 이러한 이유로, 비어 있지 않은 비주얼 C의 C++ 프로젝트에서 STDAFX.H 같은 자동 생성 된 헤더는 같은 일부 임의의 문자열이 추가합니다.#이의 헤더를 포함 코드에서

#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 

namespace somecomponent 
{ 
    ... 
} 

#endif 
+4

두 개의 밑줄로 인해 예약 된 이름입니다. 따라서 그것을 사용하는 것은 좋은 습관이 아닙니다. –

4

봐 : 파일이 일부 서브 모듈의 일부, 또는 그 내용이 하나 개의 특정 공간에있는 경우

또한, 나도 가드에 그것을 추가하는 경향이 .

이 같은 경우 :

#include "mylib/myheader.h" 

mylib/myheader.h 이미 고유 이름은. /와 및 대문자로 바꾸십시오. 당신은 당신이 포함 경로에 같은 이름의 상대와 경로를 포함에 두 개의 헤더가있는 경우 _

#define MYLIB_MYHEADER_H 

, 당신은 이미 그 수준에서 충돌이와 함께.

16

개인적으로 Boost 님의 추천을 따르십시오. 그것은 아마도 좋은 품질의 C++ 라이브러리 중 가장 큰 컬렉션 중 하나 일 것이고 그들은 문제가 없습니다.

이 같은 간다 :

<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED 

// include/pet/project/file.hpp 
#ifndef PET_PROJECT_FILE_HPP_INCLUDED 

인 :

  • 법률 (_[A-Z]로 그 시작을주의 또는 __를 포함하는 것은 아니다)
  • 쉽게
  • 은 고유 보장 생성 (포함 경비로) (다른 곳에는 같은 장소에 두 개의 파일이 있습니다)
  • 내가 GUID에 대해 읽었습니다하지만, 그 이상한 모양

(당신이 싸움을 망치고있어 INCLUDED와 다른 매크로를 종료하는 경우)하지 보장210

  • 는 다른 용도로 사용할 수 있습니다.

    그리고 분명히 차라리 모든 컴파일러보다 #pragma once 구현하는 것 (기본 동작을하거나 더 나은, #pragma multiple을하고 "일단 것은"수 ...)

  • +0

    개인적으로 저는 확장을 추가하는 것이 불필요하다고 생각하지만 _INCLUDED가 실제로 의미하는 바를 말합니다. 필자가 선호하는 것은 INCLUDE_GUARD_FOO를 사용하는 것입니다 (여분의 _H가 없으면 머리말에 대한 보호 장치가 필요합니다.) 나중에 imho라는 점이 조금 더 있지만, 실제로는 맛의 문제입니다. – cmaster

    +0

    @ cmaster _H 추가는 .h 및 .hpp 파일을 각각 사용하여 일부 기능의 C 및 C++ 구현이있는 상황에서 유용 할 수 있습니다. – Squirrel