문제

Visual Studio 2008에서 대규모 C++ 프로젝트를 작업 중인데 불필요한 파일이 많이 있습니다. #include 지시문.때로는 #includes는 단지 아티팩트일 뿐이며 제거하면 모든 것이 잘 컴파일됩니다. 다른 경우에는 클래스를 앞으로 선언하고 #include를 다음으로 이동할 수 있습니다. .cpp 파일.이 두 가지 경우를 모두 감지할 수 있는 좋은 도구가 있습니까?

도움이 되었습니까?

해결책

불필요한 포함 파일은 표시되지 않지만 Visual Studio에는 설정이 있습니다. /showIncludes (오른쪽 클릭 .cpp 파일, Properties->C/C++->Advanced) 컴파일 타임에 포함된 모든 파일의 트리를 출력합니다.이는 포함할 필요가 없는 파일을 식별하는 데 도움이 될 수 있습니다.

또한 pimpl 관용어를 살펴보고 더 적은 헤더 파일 종속성을 사용하여 제거할 수 있는 잔해를 더 쉽게 확인할 수 있습니다.

다른 팁

PC 린트 이 작업은 매우 잘 작동하며 다른 모든 종류의 바보 같은 문제도 찾아줍니다.Visual Studio에서 외부 도구를 만드는 데 사용할 수 있는 명령줄 옵션이 있지만 시각적 린트 addin이 작업하기 더 쉽습니다.무료 버전의 Visual Lint도 도움이 됩니다.하지만 PC-Lint를 시도해 보세요.너무 많은 경고를 표시하지 않도록 구성하는 데는 약간의 시간이 걸리지만 그 결과에 놀랄 것입니다.

새로운 Clang 기반 도구가 있습니다. 당신이 사용하는 것을 포함, 이를 목표로 합니다.

!!부인 성명!!저는 상용 정적 분석 도구(PC Lint 아님)를 작업하고 있습니다.!!부인 성명!!

간단한 비파싱 접근 방식에는 몇 가지 문제가 있습니다.

1) 과부하 세트:

오버로드된 함수에는 다른 파일에서 가져온 선언이 있을 수 있습니다.하나의 헤더 파일을 제거하면 컴파일 오류가 아닌 다른 오버로드가 선택될 수도 있습니다!그 결과 나중에 추적하기가 매우 어려울 수 있는 의미 체계의 자동 변경이 발생합니다.

2) 템플릿 전문화:

오버로드 예제와 유사하게 템플릿에 대한 부분적 또는 명시적 특수화가 있는 경우 템플릿을 사용할 때 모두 표시되기를 원합니다.기본 템플릿에 대한 전문화는 다른 헤더 파일에 있을 수 있습니다.특수화가 포함된 헤더를 제거하면 컴파일 오류가 발생하지 않지만 해당 특수화가 선택된 경우 정의되지 않은 동작이 발생할 수 있습니다.(보다: C++ 함수의 템플릿 전문화 가시성)

'msalters'에서 지적한 대로 코드 전체 분석을 수행하면 클래스 사용 분석도 가능합니다.특정 파일 경로를 통해 클래스가 사용되는 방식을 확인하면 클래스 정의(따라서 모든 종속 항목)를 완전히 제거하거나 최소한 포함의 기본 소스에 더 가까운 수준으로 이동할 수 있습니다. 나무.

나는 그런 도구를 모르고 과거에 하나 작성해 볼까 생각한 적도 있었지만 해결하기 어려운 문제라는 것이 밝혀졌습니다.

소스 파일에 a.h 및 b.h가 포함되어 있다고 가정해 보겠습니다.아..가 포함되어 있어요 #define USE_FEATURE_X 그리고 b.h는 #ifdef USE_FEATURE_X.만약에 #include "a.h" 주석 처리되어 있으면 파일이 계속 컴파일될 수 있지만 예상한 대로 작동하지 않을 수 있습니다.이를 감지 프로그래밍 방식으로 중요하지 않습니다.

어떤 도구를 사용하든 빌드 환경도 알아야 합니다.ah가 다음과 같다면:

#if defined( WINNT )
   #define USE_FEATURE_X
#endif

그 다음에 USE_FEATURE_X 다음과 같은 경우에만 정의됩니다. WINNT 정의되어 있으므로 도구는 컴파일러 자체에서 생성된 지시문은 물론 헤더 파일이 아닌 컴파일 명령에 지정된 지시문도 알아야 합니다.

Timmermans와 마찬가지로 나도 이에 대한 도구에 익숙하지 않습니다.그러나 Perl(또는 Python) 스크립트를 작성하여 각 포함 줄을 한 번에 하나씩 주석 처리한 다음 각 파일을 컴파일하는 프로그래머를 알고 있습니다.


이제 Eric Raymond가 이를 위한 도구가 있습니다.

구글의 cpplint.py "사용하는 항목 포함" 규칙이 있지만(다른 많은 규칙 중에서) 내가 알 수 있는 한 "포함"은 없습니다. 오직 당신이 사용하는 것." 그럼에도 불구하고 그것은 유용할 수 있습니다.

이 주제에 일반적으로 관심이 있다면 Lakos의 글을 확인해 보세요. 대규모 C++ 소프트웨어 설계.약간 오래되었지만 포함되어야 하는 헤더의 최소 개수를 찾는 것과 같은 많은 "물리적 설계" 문제를 다루고 있습니다.나는 다른 곳에서는 이런 종류의 논의를 실제로 본 적이 없습니다.

주다 관리자 포함 시도.Visual Studio에 쉽게 통합되고 포함 경로를 시각화하여 불필요한 항목을 찾는 데 도움이 됩니다.내부적으로는 Graphviz를 사용하지만 더 많은 멋진 기능이 있습니다.그리고 상용제품임에도 불구하고 가격이 매우 저렴합니다.

다음을 사용하여 포함 그래프를 작성할 수 있습니다. C/C++ 파일 종속성 감시자 포함, 시각적으로 불필요한 포함을 찾습니다.

헤더 파일이 일반적으로 다음으로 시작하는 경우

#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#endif

(#pragma를 한 번 사용하는 것과 반대로) 다음과 같이 변경할 수 있습니다.

#ifndef __SOMEHEADER_H__
#define __SOMEHEADER_H__
// header contents
#else 
#pragma message("Someheader.h superfluously included")
#endif

그리고 컴파일러는 컴파일되는 cpp 파일의 이름을 출력하므로 적어도 어떤 cpp 파일이 헤더를 여러 번 가져오도록 하는지 알 수 있습니다.

PC-Lint는 실제로 이것을 할 수 있습니다.이를 수행하는 한 가지 쉬운 방법은 사용되지 않은 포함 파일만 감지하고 다른 모든 문제를 무시하도록 구성하는 것입니다.이는 매우 간단합니다. 메시지 766("모듈에서 사용되지 않는 헤더 파일")만 활성화하려면 명령줄에 -w0 +e766 옵션을 포함시키기만 하면 됩니다.

964("모듈에서 직접 사용되지 않는 헤더 파일") 및 966("모듈에서 사용되지 않는 간접적으로 포함된 헤더 파일")과 같은 관련 메시지에도 동일한 접근 방식을 사용할 수 있습니다.

FWIW 저는 지난주 블로그 게시물에서 이에 대해 더 자세히 썼습니다. http://www.riverblade.co.uk/blog.php?archive=2008_09_01_archive.xml#3575027665614976318.

불필요한 부분을 제거하고 싶다면 #include 빌드 시간을 줄이기 위해 파일을 사용하면 다음을 사용하여 빌드 프로세스를 병렬화하는 데 시간과 비용을 더 잘 투자할 수 있습니다. cl.exe /MP, -j를 만드세요, Xoreax IncrediBuild, distcc/아이스크림, 등.

물론, 이미 병렬 빌드 프로세스가 있고 속도를 높이려고 노력하고 있다면 꼭 정리하세요. #include 지시문을 삭제하고 불필요한 종속성을 제거합니다.

각 포함 파일로 시작하고 각 포함 파일에는 자체 컴파일에 필요한 것만 포함되어 있는지 확인하십시오.C++ 파일에서 누락된 포함 파일은 C++ 파일 자체에 추가할 수 있습니다.

각 포함 및 소스 파일에 대해 각 포함 파일을 한 번에 하나씩 주석 처리하고 컴파일되는지 확인합니다.

포함 파일을 알파벳순으로 정렬하는 것도 좋은 생각이며, 이것이 가능하지 않은 경우 주석을 추가하십시오.

다음 #defines 중 하나 또는 둘 다를 추가하면 종종 불필요한 헤더 파일을 제외하고 Windows API 기능을 사용하지 않는 코드가 특히 컴파일 시간을 실질적으로 개선 할 수 있습니다.

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN

보다 http://support.microsoft.com/kb/166474

아직 포함하지 않은 경우 미리 컴파일된 헤더를 사용하여 변경하지 않을 모든 항목(플랫폼 헤더, 외부 SDK 헤더 또는 이미 완료된 프로젝트의 정적 부분)을 포함하면 빌드 시간이 크게 달라집니다.

http://msdn.microsoft.com/en-us/library/szfdksca(VS.71).aspx

또한 프로젝트에 너무 늦을 수 있더라도 프로젝트를 섹션으로 구성하고 모든 로컬 헤더를 하나의 큰 기본 헤더로 묶지 않는 것이 약간의 추가 작업이 필요하기는 하지만 좋은 습관입니다.

Eclipse CDT로 작업한다면 시도해 볼 수 있습니다. http://includator.com 포함 구조를 최적화합니다.그러나 Includator는 VC++의 사전 정의된 포함에 대해 충분히 알지 못할 수 있으며 올바른 포함과 함께 VC++를 사용하도록 CDT를 설정하는 것은 아직 CDT에 내장되어 있지 않습니다.

최신 Jetbrains IDE인 CLion은 현재 파일에서 사용되지 않는 포함 항목을 자동으로 (회색으로) 표시합니다.

IDE에서 사용되지 않은 모든 포함 항목(및 함수, 메서드 등)의 목록을 갖는 것도 가능합니다.

기존 답변 중 일부는 어렵다고 말합니다.이는 실제로 사실입니다. 전방 선언이 적절한 경우를 감지하려면 전체 컴파일러가 필요하기 때문입니다.기호의 의미를 모르면 C++를 구문 분석할 수 없습니다.그러기에는 문법이 너무 모호합니다.특정 이름이 클래스 이름인지(앞으로 선언 가능) 또는 변수 이름인지(불가능) 알아야 합니다.또한 네임스페이스를 인식해야 합니다.

조금 늦었을 수도 있지만, 여러분이 원하는 대로 작동하는 WebKit Perl 스크립트를 발견한 적이 있습니다.제가 믿기로는 약간의 적응이 필요할 것입니다(나는 Perl에 정통하지 않습니다). 그러나 그것은 트릭을 수행해야 합니다:

http://trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes

(트렁크에 더 이상 파일이 없기 때문에 이것은 오래된 브랜치입니다)

더 이상 필요하지 않다고 생각하는 특정 헤더가 있다면 (String.h), 다음에 포함 된 다음 모든 내용을 포함시킬 수 있습니다.

#ifdef _STRING_H_
#  error string.h is included indirectly
#endif

물론 인터페이스 헤더는 CPP 메모리에 포함 된 다른 #define 컨벤션을 사용하여 CPP 메모리에 포함시킬 수 있습니다.또는 규칙이 없으며,이 경우이 접근법은 작동하지 않습니다.

그런 다음 다시 빌드하십시오.세 가지 가능성이 있습니다:

  • 괜찮아요.String.h는 크리티컬이 아니었고 포함에 포함시킬 수 있습니다.

  • #오류 여행.String.g는 간접적으로 포함되어 String.h가 필요한지 여전히 알 수 없습니다.필요한 경우 직접 #include (아래 참조)을 직접 확인해야합니다.

  • 다른 컴파일 오류가 발생합니다.String.h가 필요했고 간접적으로 포함되지 않았으므로 포함이 맞았습니다.

.h 또는 .c가 다른 .h를 직접 사용하는 경우 간접 포함에 따라 거의 확실히 버그입니다.실제로 코드가 사용하는 다른 헤더가 필요로하는 한 코드 만 해당 헤더 만 요구할 것이라고 약속하고 있습니다.

건물 실패를 유발하는 것들이 여기에 적용되는 행동을 선언하는 행동을 수정하는 헤더에 대한 다른 답변에 언급 된 경고.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top