2011-02-01 2 views
0

This question은 C++ 포함 가드의 명명 규칙을 설명하는 몇 가지 중 하나입니다. 그 질문을하는 사람이 이름 지정 규칙을 생각 : 자체 촬영 (? FOO_H 무슨 뜻) 내가 동의하는 경향이 때C++의 유효한 사용법에는 include-guarding 외에 guard가 포함되어 있습니까?

#ifndef FOO_H 
#define FOO_H 

// ... 

#endif 

조금 비 직관적이다.

기타 그것의 목적이 무엇인지는 문맥에서 분명하기 때문에, 필요성을 금지하는 것은, 이름 FOO_H 그냥 괜찮 (PROJECTNAME_FOO_H_SDFFGH69876GF을 같은) 더 나은 충돌 회피를 위해 더 많은 물건을 추가 할 수 있다고 (즉,이 파일의 시작 부분입니다 같은 이름의 것이고 포함 경비원이라는 것이 분명합니다.)

FOO_H의 유일한 목적이 여러 포함을 방지하는 것이지만이 파일을 다른 곳의 FOO_H에두고 싶은 조건이 있으면이 파일을 살 수 있습니까? 나는 조건부 컴파일이 좋은 이유가 될 것이라고 생각할 것이다. 어떤 경우에는 FOO_H_INCLUDED과 같은 이름이 명확해질 것이다.

똑같은 용도가 있습니까? 아니면 포함 경비원의 용도를 변경하지 않아야합니까?

+1

나는 혼자두고 싶습니다. 이것은 깨진 것이 아니라면 "유형 상황이 될 때까지 계속 고쳐야합니다. –

+0

그래서 '#pragma once'를 선호합니다. – James

+0

@James :'#pragma once'는 조건부 컴파일로 OP를 언급하지 못하게합니다. –

답변

4

나는 그 자체로 결함이 있다고 생각한다. 경비원을 포함하는 용어는 #define을 말하며 의 복수 사용을 지키려는의 특별한 사용에 대해 #defined을 확인합니다. 이는 그 용도로만 사용되는 것입니다.

... 지금, 더 일반적으로 조금 가지고 정의하고 조건부 컴파일이 플랫폼에 의존하며 일부 상황에서 컴파일 얻을 것이다 코드의 비트를 쓰는 같은 다른 것들에 사용할 수 있습니다

FOO_H 또는 FOO_H_INCLUDED 여부 더 좋을 때, 나는 나중에 표현이 가장 표현 적이라고 말하고 나서 vi으로 가서 FOO_H을 다음번 foo.h 헤더에 입력합니다. 파일의 처음 두와 마지막 줄에

#ifndef XXXXXXXXX 
#define XXXXXXXXX 

#endif 

당신은 알아 차리지 끝 : 나는 다른 질문의 댓글에서 언급 한 바와 같이 다시, 당신은 패턴에 사용 된 성장한다. 그것은 당신이 같은 이름을 재사용하면 다시 물릴 때까지입니다 ...

1

간혹 "구현"헤더 파일로 사용합니다. 경비원의 실제 명명 방식은 다를 수 있습니다.

#ifndef FOO_IMPL_H 
#define FOO_IMPL_H 

#ifndef FOO_H 
#error Don't include this directly 
#endif 

// Ugly implementation of the stuff in foo.h, with an uncountable 
// number of template and typename keywords 

#endif 
+1

여전히 #include "foo.h"다음에 #include "foo_impl.h"가 포함되지 않습니다. 이 문제를 막으려면 Boost가 사용자에게 커튼 뒤에있는 사람을 무시해야한다는 구현 세부 정보 및 협약 (기술 시행 필요 없음)을 태그하는 데 "세부 사항"을 일관되게 사용하는 방법과 같은 더 나은 방법이 있습니다. –

1

제 생각에는 가드에 경비원을 포함시켜야합니다. 조건부 컴파일을 원하면 다른 것을 정의 할 것입니다. 코드에서 #if defined(FOO_H)을 던지고 있다면, 사람들이 보통 이상하다고 생각할 것입니다. _H은 일반적으로 포함 경비를 나타냅니다.

내가 생각할 수있는 한가지는 파일이 이미 포함되어 있는지 (duh!) 확인하여 파일을 직접 포함 할 필요가 없도록하는 것입니다. 줄에서

#include "bar.h" // comment this line to see the difference 
#include "foo.h" 

int main() 
{ 
    return 0; 
} 

을 :이 MAIN.CPP에서 선언 또는 #pragma once

을 전달하는 데 비해, 컴파일 여부를 가속화 것입니다 있는지 확실하지 않습니다.시간 : foo.h에서

#ifndef BAR_H 
#define BAR_H 

class BarClass 
{ 
}; 

#endif 

:

#ifndef FOO_H 
#define FOO_H 

#if !defined(BAR_H) 
#error bar h was not included // forgot how to do compiler warnings... 
#include "bar.h" // we should include the file 
#else 
#error bar h was included // same thing, should be changed to warning 
#endif 

// do something with BarClass 

#endif FOO_H 
+0

컴파일러는 #pragma once를 사용하지 않고 파일을 실제로 읽는 것을 건너 뛰기 위해 guard를 포함 할 수 있습니다. –

1

내가 생각하는 것 조건부 컴파일은 FOO_H_INCLUDED 같은 것이 명확 할 경우 이름에 좋은 이유가 될 것입니다.

전방 선언 만 필요할 때 헤더를 포함하지 않으려면 여기를 하나 좁게 사용하십시오. 그러나 헤더가 이전에 포함 된 경우 전달 선언을 건너 뛰고 싶습니다.

그러나 C++ 컴파일시 병목 현상이 아니므로 항상 앞쪽 선언이 있거나 항상 헤더를 포함하는 추가 혼란은 가치가 없습니다.

톤이 필요할지라도 - 그리고 앞으로 수십에서 수천 줄의 이러한 선언문을 의미합니다. 따라서 가치있게 보였으므로 < iosfwd>와 비슷한 전용 헤더를 사용하는 것이 좋습니다. 여러 곳에서.

용도 변경에 대한
1

: 파일의 전체 내용은 ifndef가에 둘러싸여하지 않는// ENDIF 정의는 다음 FOO_H 정말 파일의이 경비를 포함 파일, 그것은 단지 지키고있는 부품이 아닙니다. 따라서 파일 전체에 이름을 붙여서는 안됩니다. 동일한 파일을 재귀 적으로 포함하는 것이이 문제가 발생할 수있는 한 가지 상황입니다.

그런데, 나는 그것이 그렇다고해도 그것이 정의가 무엇인지에 대해 꽤 분명해야한다고 생각합니다. (어쨌든, 당신이하고있는 어떤 까다로운 일이라도 지키기를 포함해서 간단하지 않습니다.) 어느 곳에서나 ifndef FOO/define FOO 패턴을 보거나 심지어 ifndef FOO/많은 것들을 정의 할 수 있습니다. 간단한 코멘트는 FOO의 의미를 분명하게 만들 수 있습니다.

질문의 일부 토큰 FOO_H 이제까지 다른 목적으로 사용될 수 있는지 경우 : 당신이 생각할 사람의 rot13.h과 충돌 할 수 다음이 포함 가드로 UPPERCASE_H을 사용하는 곳 uppercase.h라는 파일이있는 경우 같아요 , 예를 들어, #define UPPERCASE_A ('N')을 포함하고 있습니다. 어리석은 예입니다.하지만 헤더 파일에 글자 속성을 정의한 경우 그 중 일부는 _H으로 끝날 것이라고 생각하는 것은 터무니 없습니다.

다른 디렉토리에 동일한 기본 이름을 포함하는 파일을 포함하는 프로젝트를보다 현실적으로 만들었습니다.

따라서 문맥 및 용도 변경과 상관없이 나는 포함 보호 장치로 FOO_H을 사용하지 않을 것입니다.