Dela via


Rensa C/C++-inkluderingar i Visual Studio

Från och med Visual Studio 17.8 Preview 1 tillhandahåller Visual Studio en #include rensningsfunktion som förbättrar kodens kvalitet på följande sätt:

  • Förslag om att lägga till headerfiler för kod som endast kompileras eftersom en nödvändig headerfil ingår indirekt via en annan headerfil.
  • Erbjudanden för att ta bort oanvända huvudfiler – förbättra byggtiderna och kodrensningen.

Funktionen 'Inkludera rensning' är som standard aktiverad. För att lära dig hur du konfigurerar det, se Config C/C++ Include Cleanup i Visual Studio.

Direkta eller indirekta rubriker

Först lite terminologi:

  • En direkt rubrik är en rubrik som du uttryckligen #include anger i koden.
  • En indirekt rubrik är en rubrik som du inte uttryckligen #include. I stället innehåller en rubrikfil som du inkluderar direkt den. Vi säger också att en indirekt rubrik ingår transitively.

Include Cleanup analyserar din kod och avgör vilka huvudfiler som inte används och vilka som är indirekt inkluderade. Överväg följande rubrikfil:

// myHeader.h

#include <string>
#include <iostream>

void myFunc()
{
    std::string s = "myFunc()\n";
    std::cout << s;
}

Och programmet som använder det:

// myProgram.cpp
#include "myHeader.h"

int main()
{
    std::string s = "main()"; // string is indirectly included by myHeader.h
    std::cout << s; // cout is indirectly included by myHeader.h
    myFunc();
}

myHeader.h är en direkt rubrik eftersom den ingår uttryckligen i myProgram.cpp. myHeader.h inkluderar <string> och <iostream>, så dessa är indirekta rubriker.

Problemet är att myProgram.cpp använder std::string och std::cout, men innehåller inte direkt rubrikerna som definierar dem. Den här koden kompileras eftersom myHeader.h inkluderar dessa headers. Den här koden är skör eftersom om myHeader.h någon gång slutade inkludera någon av dessa, skulle myProgram.cpp inte längre kompilera.

Enligt C++-riktlinjerna är det bättre att uttryckligen inkludera rubriker för alla dina beroenden så att koden inte utsätts för skörhet som orsakas av ändringar i huvudfiler. Mer information finns i SF.10: Undvik beroenden av implicita #include namn i C++ Core Guidelines.

Inkludera rensning analyserar koden för att identifiera oanvända och indirekt inkluderade rubriker. Den ger feedback baserat på inställningarna som beskrivs i Konfiguration av verktyget C++ #include i Visual Studio. Feedback kan vara i form av fellistvarningar, förslag osv. Mer information om feedbacken från Inkludera rensning finns i Inkludera rensningsmeddelanden.

Oanvända rubriker

När koden utvecklas kanske du inte längre behöver några huvudfiler. Det är svårt att hålla reda på i ett komplext projekt. Med tiden kan dina versioner ta längre tid eftersom kompilatorn bearbetar onödiga huvudfiler. Ta med rensning hjälper dig att hitta och ta bort oanvända rubriker. Till exempel, vad skulle hända om myFunc() kommenteras ut i myProgram.cpp:

// myProgram.cpp
#include "myHeader.h"

int main()
{
    std::string s = "main()"; // string is indirectly included from myHeader.h
    std::cout << s; // cout is indirectly included from myHeader.h
    // myFunc(); // directly included from myHeader.h
}

I följande skärmbild är #include "myHeader.h" nedtonad (en inställning som beskrivs i Konfigurera verktyget C++ #include i Visual Studio) eftersom det inte används när myFunc() har kommenterats ut.

Hovra markören över den nedtonade #include för att ta upp snabbåtgärdsmenyn. Klicka på glödlampan (eller välj länken Visa potentiella korrigeringar ) för att se åtgärder relaterade till den oanvända filen:

Tre refaktoriseringsalternativ visas: Ta bort #include myHeader.h, ta bort alla oanvända includes, och lägg till alla transitivt använda samt ta bort alla oanvända #includes.

Lägga till transitivt använda rubriker

Vi kan välja att ta bort den oanvända headerfilen, men det bryter koden eftersom <string> och <iostream> är indirekt inkluderade via myheader.h.

I stället kan vi välja Lägg till alla transitivt använda och ta bort alla oanvända #includes. Detta tar bort den oanvända rubriken myHeader.h, men lägger även till alla rubriker som används som indirekt ingår via myHeader.h. Resultatet i det här fallet är att lägga till #include <string> och #include <iostream> till myProgram.cppoch ta bort #include "myHeader.h":

// myProgram.cpp
#include <iostream>
#include <string>

int main()
{
    std::string s = "main()"; // string is directly included from <string>
    std::cout << s; // cout is directly included from <string>
    // MyFunc();
}

Verktyget uppdaterar inte kommentarerna, men du kan se att koden nu använder std::string och std::cout direkt. Den här koden är inte längre spröd eftersom den inte är beroende av myHeader.h att inkludera de andra nödvändiga rubrikerna.

Bästa praxis

Ta inte bort det som verkar vara oanvända huvudfiler utan att först lägga till indirekt inkluderade huvudfiler. Det beror på att koden kan förlita sig på indirekta inkluderingar i en rubrikfil som annars inte används. Lägg först till transitivt använda rubriker. När du sedan tar bort oanvända rubriker får du inte kompileringsfel på grund av saknade huvudfiler som ingår indirekt av en rubrikfil som du har tagit bort.

Ett sätt att göra detta är att ange inställningen Inkludera rensning för Lägg till saknade inkluderar förslagsnivå till Förslag (Verktyg>Alternativ>Textredigerare>C/C++>Kodrensning). Ställ också in ta bort oanvända inkluderingsförslagsnivån till Förslag. Då:

  1. Kontrollera att filtret är inställt på Build + IntelliSense i fellistan.
  2. Leta efter instanser av "Innehåll från #include x används i den här filen och ingår transitivt".
  3. Hovra markören över en linje med förslaget. I listrutan för glödlampan väljer du Lägg till alla transitivt använda inkluderingar.
  4. Upprepa de här stegen i projektet tills alla förslag om transitiva inkluderar åtgärdas.
  5. Ta bort oanvända inkluderar: I fellistan letar du efter en instans av "#include x används inte i den här filen".
  6. Hovra markören över den oanvända rubriken. I listrutan för glödlampan väljer du Ta bort alla oanvända inkluderar.
  7. Upprepa de här stegen i projektet tills alla förslag på rensning av innehåll har åtgärdats.

I den här korta översikten har du sett hur Inkludera rensning kan hjälpa dig att ta bort oanvända rubriker och lägga till rubriker som indirekt har inkluderats. Detta hjälper dig att hålla koden ren, potentiellt skapa snabbare och minskar kodens skörhet.

Se även

Konfigurera C/C++ Inkludera rensning i Visual Studio
Inkludera rensningsmeddelanden