programing

C/C++ 포함 헤더 파일 순서

prostudy 2022. 6. 1. 17:37
반응형

C/C++ 포함 헤더 파일 순서

파일을 포함하는 순서를 지정합니다.즉, 어떤 헤더를 다른 헤더보다 먼저 포함하는 이유는 무엇입니까?

예를 들어 시스템 파일, STL 및 Boost는 로컬 포함 파일 앞 또는 뒤에 있습니까?

컴파일만 되면 추천할 만한 순서는 없을 것 같아요!짜증나는 것은 일부 헤더가 다른 헤더를 먼저 포함하도록 요구하는 경우입니다.이는 헤더 자체의 문제이지 포함 순서의 문제가 아닙니다.

개인적으로는 각 서브섹션을 알파벳 순서로 로컬에서 글로벌로 이동하는 것을 선호합니다.

  1. 이 cpp 파일에 대응하는h 파일(해당하는 경우)
  2. 같은 컴포넌트의 헤더,
  3. 다른 컴포넌트의 헤더,
  4. 시스템 헤더

1는 각 헤더가 1.임을 입니다.#include ( is "technicalus " " " " " " " " " " " " " " " " " " " ) 。나머지는 논리적으로 흘러가는 것 같아요

중요한 점은 헤더가 먼저 포함된 다른 헤더에 의존하지 않아야 한다는 것입니다.이를 확인하는 한 가지 방법은 다른 헤더보다 먼저 헤더를 포함시키는 것입니다.

특히 "Thinking in C++"는 Lakos의 "Large Scale C++ Software Design"에 대해 다음과 같이 언급하고 있습니다.

컴포넌트의 .h 파일이 외부에서 제공된 선언이나 정의를 사용하지 않고 그 자체로 해석되도록 함으로써 잠재적인 사용 오류를 방지할 수 있습니다..c 파일의 첫 번째 줄에 .h 파일을 포함하면 컴포넌트의 물리 인터페이스에 고유한 중요한 정보가 .h 파일에서 누락되지 않습니다(있는 경우 .c 파일을 컴파일하려고 하면 바로 알 수 있습니다).

즉, 다음 순서로 포함합니다.

  1. 이 실장의 프로토타입/인터페이스 헤더(즉, 이 .cpp/.cc 파일에 대응하는 .h/.hh 파일).
  2. 필요에 따라 동일한 프로젝트의 다른 헤더.
  3. 다른 비표준, 비시스템 라이브러리(Qt, Igen 등)의 헤더.
  4. 다른 "거의 표준" 라이브러리의 헤더(Boost 등)
  5. 표준 C++ 헤더(iostream, 기능 등)
  6. 표준 C 헤더(cstdint, derent.h 등)

이 순서에 포함되는 것에 문제가 있는 헤더가 있는 경우는, 수정하거나 사용하지 말아 주세요.깨끗한 헤더를 쓰지 않는 라이브러리를 거부합니다.

구글의 C++ 스타일 가이드는 거의 그 반대라고 주장하지만, 명분이 전혀 없습니다.는 개인적으로 라코스의 접근방식을 선호하는 경향이 있습니다.

저는 대부분의 문제를 회피하는 두 가지 간단한 규칙을 따릅니다.

  1. 모든 헤더( 실제로 모든 소스 파일)에는 필요한 내용이 포함되어야 합니다.그들은 사물을 포함한 사용자들에게 의존해서는 안 된다.
  2. 부가적으로 위의 규칙 1을 과도하게 적용하여 여러 번 포함되지 않도록 모든 헤더에 가드를 포함해야 합니다.

또, 다음의 가이드 라인에 따릅니다.

  1. 먼저 시스템 헤더를 구분선에 포함합니다(stdio.h 등).
  2. 논리적으로 그룹화하세요.

즉, 다음과 같습니다.

#include <stdio.h>
#include <string.h>

#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"

하지만, 가이드라인으로서 그건 주관적인 것입니다.한편, 규칙에는 엄격하게 적용됩니다.가드와 그룹화된 '워퍼' 헤더 파일을 제공하는 경우에도 일부 불쾌한 서드파티 개발자가 제 비전에 가입하지 않은 경우 등이 포함됩니다.

벽에 내 벽돌을 붙이기 위해서.

  1. 각 헤더는 자급자족해야 합니다.이러한 헤더는 적어도 1회 이상 포함되어 있는 경우에만 테스트할 수 있습니다.
  2. 기호(매크로, 타입 등)를 도입하여 서드파티 헤더의 의미를 잘못 수정하지 않도록 한다.

그래서 저는 보통 이렇게 해요.

// 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 파일에 가장 먼저 대응하는 헤더(온전성 검사)
  • 시스템 헤더
  • 종속성 순서로 정리된 서드파티제 헤더
  • 프로젝트 헤더
  • 프로젝트 개인 헤더

또한 시스템 헤더와 별도로 각 파일은 이름 공간의 이름을 가진 폴더에 있습니다. 이러한 방식으로 파일을 추적하는 것이 더 쉽기 때문입니다.

권장사항:

  1. 빌드하고 있는 .cc 모듈의 헤더입니다.(프로젝트의 각 헤더가 프로젝트의 다른 헤더에 암묵적으로 의존하지 않도록 합니다.)
  2. C 시스템 파일
  3. C++ 시스템파일
  4. 플랫폼/OS/기타 헤더 파일(win32, gtk, openGL 등)
  5. 프로젝트의 다른 헤더 파일.

물론 가능하면 각 섹션의 알파벳 순서도 지정합니다.

한 포워드 선언을 위해 합니다.#include를 헤더 파일에 저장합니다.

【.cpp】【.cpp 바꿔 ,【.cpp.】source1.cpp include source1.h른른른할 수 가 있는 MSVC를 로 포함시켜야 .stdafx.h다른 무엇보다 먼저.

이유:를 포함하여source1.h다른 파일이 종속성 없이 독립할 수 있도록 하기 전에 말이죠. ifsource1.h 선언을 "Forward Declarations" 에 합니다.source1.h이것에 의해, 의존자에 의해서, 임의의 순서로 헤더를 포함할 수 있게 됩니다.

예제:

소스 1.h

class Class1 {
    Class2 c2;    // a dependency which has not been forward declared
};

소스 1.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.

이것은 주관적이지 않다.'에.#included 를 d자 d자 d자 d자 d자 d자 d자 d자 d자 d자 d자 d자 d자 d.STL Boost (STL 부스트)를 선택합니다.

특정 포함 순서를 결정할 때 몇 가지 개별 고려사항이 결합됩니다.내가 좀 풀게 해줘.

1. 자급식 여부 확인

많은 답변에서 포함 순서는 헤더가 자체 포함되었는지 확인하는 역할을 해야 한다고 제안합니다.테스트와 컴파일대한 고려가 뒤죽박죽이다

헤더가 자체 포함되었는지 여부를 별도로 확인할 수 있습니다.이 "정적 분석"은 컴파일 프로세스와는 무관합니다.예를 들어 run 입니다.

gcc headerfile.h -fsyntax-only

헤더 파일이 자체 포함인지 테스트하는 것은 쉽게 스크립트 작성/자동화할 수 있습니다.당신의 makefile도 그렇게 할 수 있어요.

악의는 없지만, Lakos의 책은 1996년에 나온 것이고, 그러한 다른 관심사들을 종합하는 것은 나에게 90년대식 프로그래밍처럼 들린다.즉, 에코시스템(현재의 Windows 또는 90년대 Windows?)이 있습니다.스크립트/프로세서 테스트용 툴이 없습니다.

2. 가독성

또 다른 고려사항은 가독성입니다.소스 파일을 검색할 때 어떤 파일이 포함되어 있는지 쉽게 확인할 수 있습니다.당신의 개인적 취향과 선호가 가장 중요하기 때문에, 당신은 보통 그것들을 가장 구체적인 것부터 가장 덜 구체적인 것까지 또는 그 반대로 주문합니다(나는 후자를 선호합니다).

각 그룹 내에서, 저는 보통 알파벳 순으로만 포함합니다.

3. 포함 순서는 중요합니까?

헤더 파일이 자급자족하고 있는 경우 컴파일 결과에 대해 포함 순서는 기술적으로 전혀 문제가 되지 않습니다.

즉, 자동으로 포함되지 않는 필수 매크로 정의 등 코드에 대한 특정 설계 선택사항이 없는 (의심할 수 있는?) 것입니다.이 경우 프로그램 설계를 재검토해야 합니다.물론 당신에게는 완벽하게 효과가 있을지도 모릅니다.

C/C++ 세계에서는 매우 많은 요소가 표준을 초과하기 때문에 어려운 질문입니다.

스켈라트가 말한 것처럼 헤더 파일 순서는 컴파일만 하면 큰 문제가 되지 않는다고 생각합니다.

제 생각은 이 모든 헤더에 심볼의 경합이 없다면 어떤 순서라도 상관없습니다.또, 헤더 의존성의 문제는, 결함이 있는 .h 에 #include 행을 추가하는 것으로 나중에 수정할 수 있습니다.

위의 헤더에 따라 일부 헤더가 (#if 조건을 체크함으로써) 액션을 변경할 때 실제로 문제가 발생합니다.

예를 들어 VS2005의 stdef.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

문제는 다음과 같습니다.커스텀 헤더가 있는 경우("custom")많은 컴파일러에서 사용할 필요가 있다.예를 들어, 오래된 컴파일러는 이 컴파일러는 이 컴파일러를 지원하지 않습니다.offsetof시스템 헤더에 다음과 같이 입력합니다.

#ifndef offsetof
#define offsetof(s,m)   (size_t)&(((s *)0)->m)
#endif

그리고 사용자에게 꼭 알려주시기 바랍니다.#include "custom.h" 모든 시스템 헤더 뒤에, 그렇지 않은 경우,offsetofstdef.h는 매크로 재정의 오류를 주장합니다.

앞으로 이런 일이 일어나지 않기를 바랍니다.

.cpp에 대응하는 .hpp(존재하는 경우)부터 시작하여 가장 구체적인 것부터 가장 구체적인 것까지 포함합니다.이렇게 하면 헤더 파일의 숨겨진 종속성이 자급자족하지 않는 것으로 드러납니다.

이는 미리 컴파일된 헤더를 사용하면 복잡해집니다.이를 회피하는 한 가지 방법은 프로젝트 컴파일러 고유의 것을 작성하지 않고 프로젝트 헤더 중 하나를 미리 컴파일된 헤더에 파일이 포함되어 있는 것으로 사용하는 것입니다.

이 방법은 어느 곳에서도 권장되지 않지만, 같은 길이로 사전 정렬된 파일 이름 길이로 시스템을 정렬하는 것을 좋아합니다.다음과 같은 경우:

#include <set>
#include <vector>
#include <algorithm>
#include <functional>

인크루드 오더 의존성의 수치심을 피하기 위해 다른 사람들보다 자신의 헤더를 먼저 포함하는 것이 좋다고 생각합니다.

언급URL : https://stackoverflow.com/questions/2762568/c-c-include-header-file-order

반응형