include 문, 헤더 또는 소스를 어디에 넣을까요?


106

헤더 파일이나 소스 파일에 포함을 넣어야합니까? 헤더 파일에 include 문이 포함 된 경우 해당 헤더 파일을 내 소스에 포함하면 내 소스 파일에 내 헤더에 있던 모든 포함 된 파일이 포함됩니까? 아니면 내 소스 파일에만 포함해야합니까?


2
SO에 대한 많은 이전 중복, 예를 들어 C ++에서 "include"를 넣어야하는 위치
Paul R

답변:


141

헤더 자체에 필요한 경우에만 include를 헤더에 넣으십시오.

예 :

  • 함수는 type을 반환합니다 size_t. 그런 다음 #include <stddef.h>에서 헤더 파일.
  • 함수는 strlen. 그런 다음 #include <string.h>소스 파일입니다.

2
내 함수가 유형의 인수를 취하면 size_t어떻게됩니까?
andrybak 2013

C ++로 확장하는 동일한 질문 : 내 구조체 / 클래스에 유형의 필드 / 멤버가있는 size_t경우 std::string어떻게합니까?
andrybak 2013

10
근거는 무엇입니까?
Patrizio Bertoni

유선 상황이 있고 C ++ 클래스 A에는 다른 클래스 B의 개체가 있으며 A 헤더 내부에 B 헤더를 포함하여 B 및 end-up의 포워드 선언을 사용할 수 없습니다. (포인터를 사용하면이 문제가 없습니다)
shuva

@andrybak 소스 파일은 헤더 파일을 포함해야 헤더가 포함되어 있으면 소스도 얻을 수 있습니다.
Jeremy Trifilo

27

수년 동안 이것에 대해 상당한 의견 차이가있었습니다. 한때 헤더 는 관련된 모듈에있는 내용 선언 하는 것이 전통적 이었기 때문에 많은 헤더에는 특정 요구 사항이 있습니다.#include 헤더 세트 (특정 순서로)를 . 일부 극도로 전통적인 C 프로그래머는 여전히이 모델을 따릅니다 (적어도 일부 경우에는 신뢰할 수 있음).

최근에는 대부분의 헤더를 독립형으로 만드는 움직임이 있습니다. 해당 헤더에 다른 것이 필요한 경우 헤더 자체가이를 처리하여 필요한 모든 것이 포함되도록합니다 (주문 문제가있는 경우 올바른 순서로). 개인적으로 저는 이것을 선호합니다. 특히 헤더의 순서가 중요 할 때 문제를 다시 해결하기 위해 그것을 사용하는 모든 사람을 요구하는 대신 한 번 문제를 해결합니다.

대부분의 헤더는 선언 만 포함해야합니다. 즉, 불필요한 헤더를 추가해도 (일반적으로) 최종 실행 파일에 영향을주지 않아야합니다. 최악의 경우 컴파일 속도가 약간 느려집니다.


2
모든 헤더가 두 번째 스타일로 작성되면 순서 문제가 전혀 없어야합니다. 헤더에 순서 문제가 있다는 것은 일반적으로 헤더에 필요한 모든 것을 포함하지 않았 음을 의미합니다.
Goodbye SE

12

너의 #include 의 헤더 파일이어야하고, 각 파일 (소스 또는 헤더)해야 #include헤더는 필요한 파일. 헤더 파일은#include 필요한 최소한의 헤더 파일이어야하며 소스 파일은 소스 파일만큼 중요하지는 않지만 소스 파일도 있어야합니다.

소스 파일에는 헤더가 있습니다. #include#include 에는 최대 중첩 깊이까지 헤더와 해당 헤더 등이 있습니다 . 이것이 #include헤더 파일에 불필요한 s를 원하지 않는 이유입니다 . 소스 파일에 필요하지 않은 많은 헤더 파일이 포함되어 컴파일 속도가 느려질 수 있습니다.

이것은 헤더 파일이 두 번 포함될 수 있으며 문제가 될 수 있음을 의미합니다. 전통적인 방법은 foo.h 파일과 같이 헤더 파일에 "include guards"를 넣는 것입니다.

#ifndef INCLUDE_FOO_H
#define INCLUDE_FOO_H
/* everything in header goes here */
#endif

나는이 답변이 매우 오래되었다는 것을 알고 있지만 그 이후로 #pragma를 한 번 추가했기 때문에 #includes를 선언 할 때 #ifndef를 포함하지 않아도됩니다.이 사촌을 게시했지만 더 인기있는 / 찬성 스레드가 Google 검색의 상단에있는 경향이 있습니다
Dogunbound 사냥개

6

제가 20 년 넘게 발전시킨 접근 방식은 이것입니다.

도서관을 고려하십시오.

여러 C 파일, 하나의 내부 H 파일 및 하나의 외부 H 파일이 있습니다. C 파일에는 내부 H 파일이 포함됩니다. 내부 H 파일에는 외부 H 파일이 포함됩니다.

컴파일러 POV에서 C 파일을 컴파일 할 때 계층 구조가 있음을 알 수 있습니다.

외부-> 내부-> C 코드

외부인 것이 제 3자가 라이브러리를 사용하는 데 필요한 모든 것이기 때문에 이것은 올바른 순서입니다. 내부적 인 것은 C 코드를 컴파일하는 데 필요합니다.


4

헤더 파일 A #includes헤더 파일 B와 C이면 #includesA가 포함 하는 모든 소스 파일 도 B와 C를 얻습니다 #included. 전처리 기는 말 그대로 텍스트 대체를 수행 합니다. 파일 #include <foo.h>의 텍스트로 대체 한다고 말하는 텍스트가있는 곳이면 어디에서나 텍스트 대체를 수행 foo.h합니다.

#includes헤더 또는 소스 파일에 넣어야하는지에 대한 의견이 다릅니다 . 개인적으로 #includes는 기본적으로 모두 소스 파일에 넣는 것을 선호 하지만 다른 필수 헤더없이 컴파일 할 수없는 헤더 파일은#include 해당 헤더 자체가 합니다.

그리고 모든 헤더 파일은 여러 번 포함되는 것을 방지하기 위해 포함 가드를 포함해야합니다.


4

일부 환경에서는 필요한 헤더 파일 만 포함 된 경우 컴파일이 가장 빠릅니다. 다른 환경에서는 모든 소스 파일이 동일한 기본 헤더 컬렉션을 사용할 수있는 경우 컴파일이 최적화됩니다 (일부 파일에는 공통 하위 집합 이외의 추가 헤더가있을 수 있음). 이상적으로는 여러 #include 작업이 효과가 없도록 헤더를 구성해야합니다. #include 문을 포함 할 파일의 include-guard에 대한 검사로 둘러싸는 것이 좋을 수 있지만,이 경우 해당 가드의 형식에 대한 종속성이 생성됩니다. 또한 시스템의 파일 캐싱 동작에 따라 대상이 완전히 #ifdef '되는 불필요한 #include가 오래 걸리지 않을 수 있습니다.

고려해야 할 또 다른 사항은 함수가 구조체에 대한 포인터를 사용하면 프로토 타입을 다음과 같이 작성할 수 있다는 것입니다.

void foo (struct BAR_s * bar);

범위 내에 있어야하는 BAR_s에 대한 정의없이. 불필요한 포함을 피하는 매우 편리한 접근 방식입니다.

추신-많은 내 프로젝트에서 모든 모듈이 #include 할 것으로 예상되는 파일이있을 것입니다. 여기에는 정수 크기에 대한 typedef와 몇 가지 일반적인 구조 및 공용체가 포함되어 있습니다.

typedef union {
  부호없는 긴 l;
  부호없는 짧은 lw [2];
  unsigned char lb [4];
} U_QUAD;

(예, 빅 엔디안 아키텍처로 이동하면 문제가 발생할 수 있지만 컴파일러가 공용체에서 익명 구조체를 허용하지 않기 때문에 공용체 내의 바이트에 대해 명명 된 식별자를 사용하려면 다음과 같이 액세스해야합니다. 다소 성가신 것처럼 보이는 theUnion.b.b1 등.


3

포함 된 내용 만 사용하여 빌드 할 수 있도록 모든 파일을 만드십시오. 헤더에 포함이 필요하지 않으면 제거하십시오. 큰 프로젝트에서이 규칙을 유지하지 않으면 누군가가 헤더가 아닌 해당 파일의 소비자가 사용중인 헤더 파일에서 포함을 제거 할 때 전체 빌드를 깨뜨릴 수 있습니다.


1

헤더에 넣으면 소스 파일에 include 문이 있습니다. 그러나 어떤 경우에는 소스 파일에 넣는 것이 더 낫습니다.

다른 소스에 해당 헤더를 포함하면 헤더에서도 포함을 가져 오며 항상 바람직하지는 않습니다. 사용되는 곳만 포함해야합니다.


1

상수 및 함수 선언을 선언하는 데 필요한 파일 만 헤더에 포함해야합니다. 기술적으로 이러한 포함은 소스 파일에도 포함되지만 명확성을 위해 실제로 사용해야하는 파일 만 각 파일에 포함해야합니다. 따라서 헤더에 여러 항목이 포함되지 않도록 보호해야합니다.

#ifndef NAME_OF_HEADER_H
#define NAME_OF_HEADER_H

...definition of header file...

#endif

이렇게하면 헤더가 여러 번 포함되어 컴파일러 오류가 발생하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.