code

C ++에서 이중 포함 가드 사용

codestyles 2020. 10. 28. 08:05
반응형

C ++에서 이중 포함 가드 사용


그래서 최근에 제가 일하는 곳 에서 단일 가드보다 이중 인클루드 가드를 사용하는 것에 대해 의문을 품은 토론을했습니다 . 이중 가드의미하는 바 는 다음과 같습니다.

헤더 파일, "header_a.hpp":

#ifndef __HEADER_A_HPP__
#define __HEADER_A_HPP__
...
...
#endif

헤더 또는 소스 파일에 헤더 파일을 포함하는 경우 :

#ifndef __HEADER_A_HPP__
#include "header_a.hpp"
#endif

이제 헤더 파일에서 가드를 사용하는 것이 이미 정의 된 헤더 파일이 여러 번 포함되는 것을 방지하는 것임을 이해합니다. 이는 일반적이고 잘 문서화되어 있습니다. 매크로가 이미 정의되어 있으면 전체 헤더 파일이 컴파일러에 의해 '공백'으로 표시되고 이중 포함이 방지됩니다. 충분히 간단합니다.

내가 이해하지 못하는 문제는 사용하고 #ifndef __HEADER_A_HPP__#endif주변 #include "header_a.hpp". 동료는 이것이 내포물에 두 번째 보호 계층을 추가한다고 들었지만 첫 번째 계층이 절대적으로 작업을 수행하는 경우에도 두 번째 계층이 어떻게 유용한 지 알 수 없습니다.

내가 생각 해낼 수있는 유일한 이점은 링커가 파일을 찾는 데 방해가되는 것을 완전히 차단한다는 것입니다. 이것은 컴파일 시간을 향상시키기위한 것입니까 (혜택으로 언급되지 않았 음), 아니면 여기에서 내가 보지 못하는 다른 작업이 있습니까?


다음과 같은 다른 포함 가드를 추가하는 것이 나쁜 습관이라고 확신합니다.

#ifndef __HEADER_A_HPP__
#include "header_a.hpp"
#endif

그 이유는 다음과 같습니다.

  1. 이중 포함을 방지하려면 헤더 파일 자체에 일반적인 include 가드를 추가하는 것으로 충분합니다. 그것은 일을 잘합니다. 또 하나는 포함 대신 가드를 포함하여 코드를 엉망으로 만들고 가독성을 떨어 뜨립니다.

  2. 불필요한 종속성을 추가합니다. 헤더 파일 내에서 포함 가드를 변경 하면 헤더가 포함 된 모든 위치에서 변경해야합니다 .

  3. 전체 컴파일 / 연결 프로세스를 비교할 때 가장 비용이 많이 드는 작업은 아니므로 전체 빌드 시간을 거의 줄일 수 없습니다.

  4. 가치있는 컴파일러는 이미 파일 전체 인클루드 가드를 최적화합니다 .


헤더 파일 에 포함 가드를 넣는 이유는 헤더 의 내용이 번역 단위로 두 번 이상 가져 오지 않도록하기 위함입니다. 그것은 평범하고 오랜 전통의 관행입니다.

중복 포함 가드를 소스 파일 에 넣는 이유는 포함 되는 헤더 파일을 열지 않고 컴파일 속도를 크게 높일 수 있었던 예전으로 돌아갈 필요가 없기 때문입니다. 요즘에는 파일을 여는 것이 예전보다 훨씬 빠릅니다. 또한 컴파일러는 이미 본 파일을 기억하는 데 매우 영리하며 include guard 관용구를 이해하므로 파일을 다시 열 필요가 없다는 것을 스스로 알아낼 수 있습니다. 그것은 약간의 손을 흔드는 것이지만 결론은이 추가 레이어가 더 이상 필요하지 않다는 것입니다.

편집 : 여기에 또 다른 요소는 C ++ 컴파일이 C를 컴파일하는 것보다 훨씬 복잡하기 때문에 훨씬 더 오래 걸리므로 포함 파일을 여는 데 소요되는 시간이 번역 단위를 컴파일하는 데 걸리는 시간의 더 작고 덜 중요한 부분이됩니다.


내가 생각 해낼 수있는 유일한 이점은 링커가 파일을 찾는 데 방해가되는 것을 완전히 차단한다는 것입니다.

링커는 어떤 방식으로도 영향을받지 않습니다.

전처리 기가 파일을 찾는 것을 막을 수 있지만 가드가 정의되어 있으면 이미 파일을 찾았 음을 의미합니다. 나는 전처리 시간이 전혀 줄어들면 병리학 적으로 가장 재귀 적으로 포함 된 괴물을 제외하고는 그 효과가 아주 미미할 것이라고 생각합니다.

가드가 변경된 경우 (예 : 다른 가드와의 충돌로 인해), include 지시문 이전의 모든 조건문이 작동하려면 변경되어야한다는 단점이 있습니다. 그리고 다른 것이 이전 가드를 사용하는 경우 include 지시문 자체가 올바르게 작동하도록 조건문을 변경해야합니다.

PS __HEADER_A_HPP__는 구현에 예약 된 기호이므로 정의 할 수있는 것이 아닙니다. 경비원에 다른 이름을 사용하십시오.


보다 전통적인 (메인 프레임) 플랫폼 (여기서는 2000 년대 중반)의 이전 컴파일러는 다른 답변에서 설명 된 최적화를 사용하지 않았으므로 실제로 헤더 파일을 다시 읽어야하는 전처리 시간을 상당히 늦추는 데 사용되었습니다. 이미 포함되어 있습니다 (대규모의 모 놀리 식 엔터프라이즈 프로젝트에서는 많은 헤더 파일을 포함하게 될 것입니다). 예를 들어, VisualAge C ++ 6 for AIX 컴파일러 (2000 년대 중반부터 시작)에서 동일한 256 개의 헤더 파일을 포함하는 256 개의 헤더 파일이있는 파일의 경우 26 배 속도 향상을 나타내는 데이터를 보았습니다. 이것은 다소 극단적 인 예이지만 이러한 종류의 속도 향상은 합산됩니다.

그러나 모든 최신 컴파일러는 심지어 AIX 및 Solaris와 같은 메인 프레임 플랫폼에서도 헤더 포함을위한 충분한 최적화를 수행하여 요즘 그 차이는 거의 무시할 수 있습니다. 그러므로 이것들을 더 이상 가질 이유가 없습니다.

그러나 이것은 상대적으로 최근에 (적어도 C / C ++ 코드베이스 시대 용어로) 매우 큰 모 놀리 식 프로젝트에 여전히 가치가 있었기 때문에 일부 회사가 여전히 관행에 매달리는 이유를 설명합니다.


반대하는 사람들이 있지만 실제로는 '#pragma once'가 완벽하게 작동하며 주요 컴파일러 (gcc / g ++, vc ++)가이를 지원합니다.

따라서 사람들이 퍼지는 순수한 논쟁이 무엇이든 훨씬 더 효과적입니다.

  1. 빠른
  2. 오래된 깃발을 복사했기 때문에 유지 보수가 필요없고 신비한 비 포함 문제가 없습니다.
  3. 명백한 의미가있는 한 줄과 파일에 퍼져있는 숨겨진 줄

그래서 간단히 말하면 :

#pragma once

at the start of the file, and that's it. Optimized, maintainable, and ready to go.

참고URL : https://stackoverflow.com/questions/44629152/the-use-of-double-include-guards-in-c

반응형