In alcuni ambienti, la compilazione sarà più veloce se si includono solo i file di intestazione necessari. In altri ambienti, la compilazione sarà ottimizzata se tutti i file di origine possono utilizzare la stessa raccolta primaria di intestazioni (alcuni file potrebbero avere intestazioni aggiuntive oltre al sottoinsieme comune). Idealmente, le intestazioni dovrebbero essere costruite in modo che più operazioni #include non abbiano effetto. Potrebbe essere utile racchiudere le istruzioni #include con controlli per includere-guard del file da includere, sebbene ciò crei una dipendenza dal formato di tale guardia. Inoltre, a seconda del comportamento di caching dei file di sistema, un #include non necessario il cui target finisce per essere completamente # ifdef'ed eliminato potrebbe non richiedere molto tempo.
Un'altra cosa da considerare è che se una funzione accetta un puntatore a una struttura, si può scrivere il prototipo come
void foo (struct BAR_s * bar);
senza che debba essere inclusa una definizione per BAR_s. Un approccio molto pratico per evitare include non necessari.
PS: in molti dei miei progetti, ci sarà un file che ci si aspetta che ogni modulo #includa, contenente cose come typedef per le dimensioni intere e alcune strutture e unioni comuni [es.
typedef union {
non firmato lungo l;
short lw senza segno [2];
carattere senza segno lb [4];
} U_QUAD;
(Sì, so che sarei nei guai se passassi a un'architettura big-endian, ma poiché il mio compilatore non consente le strutture anonime nelle unioni, l'utilizzo di identificatori denominati per i byte all'interno dell'unione richiederebbe l'accesso come theUnion.b.b1 ecc. che sembra piuttosto fastidioso.