C / C ++ 헤더 파일 순서 포함
어떤 순서로 파일을 포함시켜야합니까, 즉 하나의 헤더를 다른 헤더 앞에 포함시키는 이유는 무엇입니까?
예를 들어, 시스템 파일, STL 및 Boost가 로컬 포함 파일 앞뒤로 이동합니까?
컴파일 된 한 권장 순서가 있다고 생각하지 않습니다! 성가신 것은 일부 헤더가 다른 헤더를 먼저 포함해야 할 때입니다. 포함 순서가 아닌 헤더 자체에 문제가 있습니다.
개인적으로 선호하는 것은 지역에서 세계로, 각 하위 섹션을 사전 순으로하는 것입니다.
- 이 cpp 파일에 해당하는 h 파일 (해당되는 경우)
- 동일한 구성 요소의 헤더
- 다른 구성 요소의 헤더
- 시스템 헤더.
1.에 대한 나의 근거는 #include
전제 조건없이 각 헤더 (cpp가있는)가 d 가 될 수 있음을 증명해야한다는 것입니다 . 그리고 나머지는 논리적으로 거기에서 흘러 나오는 것 같습니다.
명심해야 할 것은 헤더가 먼저 포함되는 다른 헤더에 의존해서는 안된다는 것입니다. 이를 보장하는 한 가지 방법은 다른 헤더보다 먼저 헤더를 포함시키는 것입니다.
Lakos의 "대규모 C ++ 소프트웨어 디자인"을 참조하여 "C ++로 생각하기"는 특히 이것을 언급합니다.
외부 제공 선언이나 정의없이 구성 요소의 .h 파일이 자체적으로 구문 분석되도록하여 잠재적 사용 오류를 피할 수 있습니다. .h 파일을 .c 파일의 첫 번째 행으로 포함하면 중요한 부분이 없습니다. 구성 요소의 물리적 인터페이스에 내재 된 정보가 .h 파일에서 누락되었거나 존재하는 경우 .c 파일을 컴파일하려고하면 정보를 찾을 수 있습니다.
즉, 다음 순서로 포함하십시오.
- 이 구현을위한 프로토 타입 / 인터페이스 헤더 (즉,이 .cpp / .cc 파일에 해당하는 .h / .hh 파일)
- 필요에 따라 동일한 프로젝트의 다른 헤더
- 다른 비표준 비 시스템 라이브러리 (예 : Qt, Eigen 등)의 헤더
- 다른 "거의 표준"라이브러리의 헤더 (예 : Boost)
- 표준 C ++ 헤더 (예 : iostream, 기능 등)
- 표준 C 헤더 (예 : cstdint, dirent.h 등)
헤더에이 순서에 포함되는 데 문제가있는 경우 헤더를 수정하거나 사용하지 마십시오. 깔끔한 헤더를 작성하지 않는 보이콧 라이브러리.
구글의 C ++ 스타일 가이드는 주장 거의 모두 정말 정당화와, 반대로; 나는 개인적으로 Lakos 접근법을 선호하는 경향이 있습니다.
나는 대부분의 문제를 피하는 두 가지 간단한 규칙을 따릅니다.
- (실제로 모든 헤더 모든 소스 파일) 그들이 필요로하는 것을 포함해야한다. 사물을 포함하여 사용자에게 의존 해서는 안됩니다 .
- 부가 적으로, 모든 헤더에는 위의 규칙 1을 과도하게 적용하여 여러 번 포함되지 않도록 가드가 있어야합니다.
또한 다음 지침을 따릅니다.
- 구분선이있는 시스템 헤더를 먼저 포함하십시오 (stdio.h 등).
- 논리적으로 그룹화하십시오.
다시 말해:
#include <stdio.h>
#include <string.h>
#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"
비록 지침이기는하지만 주관적인 것입니다. 반면에 규칙은 난해한 타사 개발자가 내 비전에 가입하지 않은 경우 포함 가드 및 그룹화 된 포함으로 '래퍼'헤더 파일을 제공하는 시점까지 엄격하게 시행합니다.
벽에 내 자신의 벽돌을 추가합니다.
- 각 헤더는 자급 자족해야하며, 적어도 한 번 이상 포함 된 경우에만 테스트 할 수 있습니다
- 심볼 (매크로, 유형 등)을 도입하여 타사 헤더의 의미를 실수로 수정해서는 안됩니다.
그래서 나는 보통 다음과 같이 간다 :
// myproject/src/example.cpp
#include "myproject/example.h"
#include <algorithm>
#include <set>
#include <vector>
#include <3rdparty/foo.h>
#include <3rdparty/bar.h>
#include "myproject/another.h"
#include "myproject/specific/bla.h"
#include "detail/impl.h"
각 그룹은 다음 그룹과 빈 줄로 구분됩니다.
- 이 cpp 파일에 먼저 대응하는 헤더 (신성 검사)
- 시스템 헤더
- 종속성 순서로 구성된 타사 헤더
- 프로젝트 헤더
- 프로젝트 개인 헤더
또한 시스템 헤더와는 별도로 각 파일은 네임 스페이스 이름이있는 폴더에 있습니다. 이러한 방식으로 파일을 쉽게 추적 할 수 있기 때문입니다.
나는 이것이 제정신 세계의 어느 곳에서도 권장되는 관행이 아니라고 확신하지만, 시스템 길이를 파일 이름 길이별로 정렬하고 같은 길이 내에서 어휘 적으로 정렬하고 싶습니다. 이렇게 :
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
포함 순서 종속성의 부끄러움을 피하기 위해 다른 사람들보다 자신의 헤더를 포함시키는 것이 좋습니다.
나는 추천한다 :
- 빌드중인 .cc 모듈의 헤더입니다. (프로젝트의 각 헤더가 프로젝트의 다른 헤더에 암시 적으로 종속되지 않도록합니다.)
- C 시스템 파일.
- C ++ 시스템 파일.
- 플랫폼 / OS / 기타 헤더 파일 (예 : win32, gtk, openGL).
- 프로젝트의 다른 헤더 파일.
물론 가능하면 각 섹션 내에서 알파벳 순서로 정렬됩니다.
#include
헤더 파일에서 불필요한 선언을 피하려면 항상 전달 선언을 사용 하십시오.
이것은 주관적이지 않습니다. 헤더가 #include
특정 순서 로 d에 의존하지 않도록하십시오 . STL 또는 Boost 헤더를 포함하는 순서가 중요하지 않을 수 있습니다.
먼저 .cpp ...에 해당하는 헤더를 포함하십시오. 즉, 다른 것을 source1.cpp
포함 source1.h
하기 전에 포함 해야 합니다. 내가 생각할 수있는 유일한 예외는 미리 컴파일 된 헤더와 함께 MSVC를 사용할 때입니다.이 경우 stdafx.h
다른 것보다 먼저 포함시켜야 합니다.
추론 :source1.h
다른 파일 이전을 포함하면 파일이 종속되지 않고 독립형 일 수 있습니다. 경우 source1.h
나중에에 대한 종속성 취, 컴파일러는 바로 당신이 필요한 앞으로 선언을 추가 경고합니다 source1.h
. 그러면 종속 항목이 헤더를 순서에 상관없이 포함시킬 수 있습니다.
예:
source1.h
class Class1 {
Class2 c2; // a dependency which has not been forward declared
};
source1.cpp
#include "source1.h" // now compiler will alert you saying that Class2 is undefined
// so you can forward declare Class2 within source1.h
...
MSVC 사용자 : 사전 컴파일 된 헤더를 사용하는 것이 좋습니다. 따라서 #include
표준 헤더 (및 변경되지 않는 다른 헤더)에 대한 모든 지시문을 로 이동하십시오 stdafx.h
.
.cpp에 해당하는 .hpp (있는 경우)부터 시작하여 가장 구체적인 것부터 가장 작은 것까지 포함하십시오. 이렇게하면 충분하지 않은 헤더 파일의 숨겨진 종속성이 표시됩니다.
사전 컴파일 된 헤더를 사용하면 복잡합니다. 이 문제를 해결하는 한 가지 방법은 프로젝트 컴파일러별로 만들지 않고 사전 컴파일 된 헤더 포함 파일로 프로젝트 헤더 중 하나를 사용하는 것입니다.
C / C ++ 세계에서는 어려운 질문이며 표준을 넘어서는 많은 요소가 있습니다.
squelart가 말한 것처럼 헤더 파일 순서가 컴파일되는 한 심각한 문제는 아니라고 생각합니다.
내 아이디어는 : 모든 헤더에 기호 충돌이 없으면 순서가 정상이며 결함이있는 .h에 #include 행을 추가하여 헤더 종속성 문제를 나중에 해결할 수 있습니다.
어떤 헤더가 위에 있는지에 따라 일부 헤더가 동작을 변경하면 (#if 조건을 확인하여) 번거 로움이 발생합니다.
예를 들어 VS2005의 stddef.h에는 다음이 있습니다.
#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
이제 문제 : offsetof
시스템 헤더에 제공되지 않는 일부 오래된 컴파일러를 포함하여 많은 컴파일러와 함께 사용해야하는 사용자 정의 헤더 ( "custom.h")가 있으면 헤더에 작성해야합니다.
#ifndef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
그리고 모든 시스템 헤더 #include "custom.h"
다음에 사용자에게 알려주십시오 . 그렇지 않으면 offsetof
stddef.h 의 행에 매크로 재정의 오류가 발생합니다.
우리는 경력에서 더 이상 그러한 경우를 만나지 않기를기도합니다.
참고 URL : https://stackoverflow.com/questions/2762568/cc-include-header-file-order
'IT' 카테고리의 다른 글
LINQ : 전혀 그렇지 않다 (0) | 2020.03.31 |
---|---|
getattr ()이란 무엇이며 어떻게 사용합니까? (0) | 2020.03.31 |
스칼라 컨텍스트와 뷰 범위는 무엇입니까? (0) | 2020.03.31 |
PyCharm에서 항상 줄 번호를 표시하는 방법 (0) | 2020.03.31 |
.NET으로 특정 확장자를 가진 임시 파일을 어떻게 만들 수 있습니까? (0) | 2020.03.31 |