2015-12-30 10 views
10

Un codice base con cui lavoro ha storicamente cercato - volutamente - per evitare le dipendenze da stdio.h in corso. Ha una propria formattazione e meccanismi di stampa, e quelli sono cosa dovrebbe essere usato al posto di printf ecc.Impedire l'inclusione di stdio.h (o altra intestazione standard)

Ma qualcuno aggiunge una dipendenza ogni tanto che deve farsi notare ed estrarre. Così ho provato a fare un allarme per il più facile dei casi:

#if !defined(NDEBUG) 
    void printf(float dont_link_with_stdio_h); 
#endif 

La gente gcc sembrano essere stati pensando lungo le linee di arresto semplici errori di troppo, perché c'è un messaggio utile se fate questo ... se hai incluso <stdio.h> oppure no.

tipi contrastanti per la funzione 'printf' built-in

C'è un modo per trasformare questo avvertimento off (-fno-builtin). E ci sono tutti i tipi di approcci che farebbero cose come filtrare il deposito di simboli per cose che non vuoi essere lì ...

Ma c'è una cosa facile da non-avvertire (se non lo facevi include stdio.h) per avvisare qualcuno che ha introdotto un uso improprio di printf?

+0

Non riesci a rimuovere la versione compilata della libreria (.lib) in modo che non venga compilata/collegata? –

+0

@LeeTaylor Preferirei non manomettere l'ambiente di compilazione, che è usato per altre cose che includono questa libreria (e quelle cose sono libere di includere stdio.h se lo desiderano). Sto cercando qualcosa di meno invadente rispetto all'uso del metodo che stavo cercando e aggiungendo '-fno-builtin' ... ad es. qualcosa che può essere fatto all'interno della fonte da solo. – HostileFork

+0

'grep printf * .c'? –

risposta

5

È possibile ridefinire printf di essere un valore brutto che causerà un errore di compilazione o di collegamento. Per esempio:

#define printf do_not_include_stdio_h 
#include <stdio.h> 

int main(void) { 
    printf("Hello, world!\n"); 
    return 0; 
} 

produces the output:

undefined reference to `do_not_include_stdio_h'

È possibile munge la macro, se si vuole che sia un nome di ancora più oscuro o includere i simboli non validi se siete preoccupati che qualche povera anima avrà definito do_not_include_stdio_h.

È possibile impostare la definizione della macro nei flag del compilatore in modo da non dover modificare manualmente i file. Ad esempio:

gcc -Dprintf=do_not_include_stdio_h my_file.c 
2

Per impedire l'inclusione di <stdio.h>, vorrei andare con

#if !defined(NDEBUG) 
#if defined(EOF) 
#error Do not include stdio.h, contact Joe for more information 
#endif 
#endif 
+1

Bello ... anche se il problema sarebbe che avrebbe fermato le inclusioni solo se questa inclusione fosse * dopo * stdio.h. Vorrei anticiparlo se questa intestazione fosse inclusa anche in precedenza ... – HostileFork

3

Non toccarei affatto i file di origine. Modificherei lo script di compilazione. Molto più facile da mantenere e molto più facile da impedire alle persone di eludere la restrizione (ad esempio cambiando il codice che causa il fallimento della compilazione).

Per esempio, in un makefile, supponendo che hanno un all destinazione che costruire tutto

all: 

    grep stdio *.h *.c 
    if ["$?" -eq 0 ]; then 
     echo "Do not use stdio. Contact Joe for info"; exit 2; 
    fi 

    <other stuff to do the build here> 

È anche possibile farlo su particolari obiettivi. Ad esempio, se si dispone di una destinazione che compila un file .c per produrre un file .o, è sufficiente controllare il file .c prima di compilarlo.

%.o : %.c 

     grep stdio $< 
     if ["$?" -eq 0 ]; then 
      echo "Do not use stdio. Contact Joe for info"; exit 2; 
     fi 

     $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o [email protected] 

Il vostro unico problema ora è che cosa fare se hai qualcuno che è determinato a bypassare il vostro restrizione (ad esempio da dove #include "bypass.joe"bypass.joe ha un #include <stdio.h>).Per questo, cerca gli strumenti per generare dipendenze (ad esempio gcc -MM, makedepend, ecc.) E usalo per impostare un metodo per cercare tutti i file su cui i tuoi file sorgente dipendono. Se qualcuno è così determinato, imposta anche le protezioni sui tuoi makefile in modo che solo tu possa modificarle.

MODIFICA: se si dispone di un set di strumenti per generare un file di dipendenza, cercare semplicemente tale file per stdio. Se un'unità di compilazione, direttamente o indirettamente, include stdio.h, verrà elencata nel file delle dipendenze.

+0

Il problema con grepping come questo (oltre ad essere invasivo per i makefile che preferirei evitare in quanto sono generati da un altro processo) è che quindi hai preoccupazioni come se fosse in un commento, e se fosse # ifdef'd out e non applicabile, ecc. Ci sono alcuni file di terze parti che sono .c che hanno i loro flag in modalità debug separati, quindi non ci sarebbe devono essere elenchi di eccezioni, ecc ... – HostileFork

+0

Data una scelta di essere "invasivo" su un makefile e di essere "invasivo" su tutte le unità di compilazione (cioè file sorgenti) in un progetto, sceglierei il primo. Anche in un progetto complesso, il numero di makefile supera raramente il numero di unità di compilazione. Esistono tecniche per garantire la gestione personalizzata all'interno dei makefile generati automaticamente, utilizzando make ricorsivamente, ecc. – Peter

+0

Ragionevoli, e grazie per l'opzione, upvoted. Ma per il mio caso particolare la scelta migliore nel bilanciamento è di non toccare i makefile ... – HostileFork

Problemi correlati