Condividi tramite


Pulire C/C++ include in Visual Studio

A partire da Visual Studio 17.8 Preview 1, Visual Studio offre una #include funzionalità di pulizia che migliora la qualità del codice nei modi seguenti:

  • Offre di aggiungere file di intestazione per il codice che viene compilato solo perché un file di intestazione necessario è incluso indirettamente da un altro file di intestazione.
  • Offre la rimozione dei file di intestazione inutilizzati, migliorando i tempi di compilazione e la pulizia del codice.

Includi Pulizia è attivata per impostazione predefinita. Per informazioni su come configurarlo, vedere Config C/C++ Include Cleanup in Visual Studio.

Intestazioni dirette e indirette

Prima di tutto una terminologia:

  • Un'intestazione diretta è un'intestazione in modo esplicito #include nel codice.
  • Un'intestazione indiretta è un'intestazione che non è esplicitamente #include. Include invece un file di intestazione che si include direttamente. Si supponga anche che sia inclusa transitivelyun'intestazione indiretta.

Includi Pulizia analizza il codice e determina quali intestazioni non vengono usate e quali sono incluse indirettamente. Si consideri il file di intestazione seguente:

// myHeader.h

#include <string>
#include <iostream>

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

E il programma che lo usa:

// 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 è un'intestazione diretta perché myProgram.cpp la include in modo esplicito. myHeader.h include <string> e <iostream>, quindi queste sono intestazioni indirette.

Il problema è che myProgram.cpp usa std::string e std::cout, ma non include direttamente le intestazioni che le definiscono. Questo codice viene compilato perché myHeader.h include tali intestazioni. Questo codice è fragile perché, se myHeader.h mai interrotto, incluso uno di essi, myProgram.cpp non verrà più compilato.

In base alle linee guida per C++, è preferibile includere in modo esplicito le intestazioni per tutte le dipendenze, in modo che il codice non sia soggetto alla fragilità causata dalle modifiche apportate ai file di intestazione. Per altre informazioni, vedere Linee guida di base di C++ SF.10.

Includi Pulizia analizza il codice per identificare le intestazioni incluse indirettamente e inutilizzate. Fornisce commenti e suggerimenti in base alle impostazioni descritte in Configurazione dello strumento di #include C++ in Visual Studio. Il feedback può essere sotto forma di avvisi di elenco errori, suggerimenti e così via. Per altri dettagli sui commenti e suggerimenti forniti da Includi pulizia, vedere Includi messaggi di pulizia.

Intestazioni inutilizzate

Man mano che il codice si evolve, potrebbe non essere più necessario alcun file di intestazione. Questo è difficile tenere traccia di in un progetto complesso. Nel corso del tempo, le compilazioni potrebbero richiedere più tempo perché il compilatore sta elaborando file di intestazione non necessari. Includi Pulizia consente di trovare e rimuovere intestazioni inutilizzate. Ad esempio, cosa accade se myFunc() viene impostato come commento in 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
}

Nello screenshot seguente, #include "myHeader.h" è disattivata (un'impostazione descritta in Config the C++ #include tool in Visual Studio) perché non viene usata perché myFunc() è impostata come commento.

Passare il cursore sull'ombreggiatura #include per visualizzare il menu azione rapida. Fare clic sulla lampadina (o scegliere il collegamento Mostra potenziali correzioni ) per visualizzare le azioni correlate al file inutilizzato:

Three refactoring options are shown: Remove # include myHeader.h, remove all unused includes, and Add all transitively used and remove all unused # includes.

Aggiungere intestazioni usate in modo transitivo

È possibile scegliere di rimuovere il file di intestazione inutilizzato, ma che interrompe il codice perché <string> e <iostream> sono indirettamente inclusi tramite myheader.h.

È invece possibile scegliere Aggiungi tutti i #includes non usati in modo transitivo e rimuovere tutti i #includes inutilizzati. In questo modo viene rimossa l'intestazione inutilizzata myHeader.h, ma vengono aggiunte anche eventuali intestazioni usate indirettamente incluse tramite myHeader.h. Il risultato, in questo caso, viene aggiunto #include <string> e #include <iostream> a myProgram.cppe rimuovendo #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();
}

Lo strumento non aggiorna i commenti, ma è possibile notare che il codice è ora in uso std::string e std::cout direttamente. Questo codice non è più fragile perché non dipende da myHeader.h includere le altre intestazioni obbligatorie.

Procedure consigliate

Non rimuovere ciò che sembra essere file di intestazione inutilizzati senza prima aggiungere file di intestazione inclusi indirettamente. Ciò è dovuto al fatto che il codice può basarsi su include indirette in un file di intestazione che altrimenti non è usato. Aggiungere prima intestazioni usate in modo transitivo. Quindi, quando si rimuovono le intestazioni inutilizzate, non si ricevono errori di compilazione a causa di file di intestazione mancanti inclusi indirettamente da un file di intestazione rimosso.

Un modo per eseguire questa operazione consiste nell'impostare l'impostazione Includi pulizia per Aggiungi elementi mancanti include il livello di suggerimento su Suggerimento (Strumenti>Opzioni>Editor>di testo C/C++>Pulizia codice). Impostare anche Rimuovi non usato include il livello di suggerimento su Suggerimento. Quindi:

  1. Nell'elenco degli errori verificare che il filtro sia impostato su Build + IntelliSense.
  2. Cercare le istanze di "Content from #include x is used in this file and transitively included".
  3. Passare il cursore su una riga con il suggerimento. Nell'elenco a discesa lampadina selezionare Aggiungi tutte le include transitive usate.
  4. Ripetere questi passaggi nel progetto fino a quando non vengono risolti tutti i suggerimenti relativi alle include transitive.
  5. Rimuovere le include inutilizzate: nell'elenco degli errori cercare un'istanza di "#include x non viene usata in questo file".
  6. Passare il cursore sull'intestazione inutilizzata. Nell'elenco a discesa lampadina selezionare Rimuovi tutti i inclusi inutilizzati.
  7. Ripetere questi passaggi nel progetto fino a quando non vengono risolti tutti i suggerimenti includi pulizia.

In questa breve panoramica si è visto in che modo Include Cleanup può essere utile per rimuovere le intestazioni inutilizzate e aggiungere intestazioni incluse indirettamente. In questo modo è possibile mantenere il codice pulito, potenzialmente più veloce e ridurre la fragilità del codice.

Vedi anche

Configurare la pulizia di inclusione C/C++ in Visual Studio
Includi messaggi di pulizia