2015-12-30 3 views
10

Eine Codebase, mit der ich arbeite, hat historisch versucht - absichtlich - Abhängigkeiten zu stdio.h zu vermeiden. Es hat seine eigene Druckformatierung und Mechanismen, und das sind was anstelle von printf o.ä. verwendet werden sollVerhindern Aufnahme von stdio.h (oder anderen Standard-Header)

Aber jemand fügt manchmal eine Abhängigkeit hinzu, die bemerkt und herausgenommen werden muss. Also habe ich versucht, einen Alarm für den einfachsten Fällen zu machen:

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

Die gcc Menschen scheinen entlang der Linien des Anhaltens zu leicht Fehler zu denken haben, denn es gibt eine hilfreiche Nachricht ist, wenn Sie dies tun ... ob Sie haben <stdio.h> oder nicht enthalten.

gegensätzliche Typen für integrierte Funktion 'printf'

Es gibt einen Weg, um diese Warnung auszuschalten (-fno-builtin). Und es gibt alle Arten von Ansätzen, die Dinge wie Filter der Symbol-Dump für Dinge tun, die Sie nicht dort sein wollen ...

Aber gibt es eine trivial einfache non-warning-verursacht (wenn Sie nicht include stdio.h) um jemanden darauf aufmerksam zu machen, dass sie eine unerwünschte Drucknutzung eingeführt haben?

+0

Können Sie die kompilierte Version der Bibliothek (.lib) nicht entfernen, damit sie nicht kompiliert/verlinkt wird? –

+0

@LeeTaylor Ich würde es vorziehen, nicht die Kompilierungsumgebung zu manipulieren, die für andere Dinge verwendet wird, die diese Bibliothek enthalten (und diese Dinge sind frei, um stdio.h aufzunehmen, wenn sie es wünschen). Ich bin auf der Suche nach etwas weniger aufdringlich als die Verwendung der Methode, die ich versuchte und Hinzufügen von "-fno-builtin" ... z. etwas, das nur in der Quelle gemacht werden kann. – HostileFork

+0

'grep printf * .c'? –

Antwort

5

Sie können printf gehen würde neu definieren einigen bösen Wert zu sein, die eine Zusammenstellung oder Verknüpfungsfehler verursachen. Zum Beispiel:

#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'

Sie das Makro munge können, wenn Sie es sich um eine noch obskurer Name oder sind ungültige Symbole sein möchten, wenn Sie sich Sorgen machen dass irgendeine arme Seele do_not_include_stdio_h definiert haben wird.

Sie können die Makrodefinition in den Compiler-Flags festlegen, sodass Sie die Datei (en) nicht manuell bearbeiten müssen. Zum Beispiel:

gcc -Dprintf=do_not_include_stdio_h my_file.c 
2

Zur Aufnahme von <stdio.h>, verhindere ich mit

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

Schön ... obwohl das Problem damit wäre, dass es nur die Einschlüsse stoppen würde, wenn diese Aufnahme * nach * stdio.h wäre. Ich möchte es vorwegnehmen, wenn dieser Header vorher auch enthalten wäre ... – HostileFork

3

Ich würde die Quelldateien überhaupt nicht berühren. Ich würde das Build-Skript ändern. Viel einfacher zu pflegen und viel einfacher zu verhindern, dass Menschen die Beschränkung umgehen (z. B. durch Ändern des Codes, der das Kompilieren zum Scheitern bringt).

Zum Beispiel in einem Make-Datei, Sie unter der Annahme haben ein all Ziel, das alles bauen

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> 

Sie auch können es auf bestimmte Ziele. Wenn Sie zum Beispiel ein Ziel haben, das eine .c-Datei kompiliert, um eine .o-Datei zu erstellen, überprüfen Sie einfach die .c-Datei, bevor Sie sie kompilieren.

%.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] 

Ihr einziges Problem ist jetzt, was zu tun ist, wenn Sie jemand, der bestimmt wird Ihre Einschränkung (zum Beispiel durch #include "bypass.joe" wo bypass.joe ein #include <stdio.h> hat) zu umgehen.Suchen Sie dazu nach Tools, um Abhängigkeiten zu generieren (z. B. gcc -MM, makedepend usw.), und richten Sie damit eine Möglichkeit ein, nach allen Dateien zu suchen, von denen Ihre Quelldateien abhängig sind. Wenn jemand bestimmt ist, setze auch Schutz auf deine Makefiles, so dass nur du sie bearbeiten kannst.

BEARBEITEN: Wenn Sie ein Tool zum Generieren einer Abhängigkeitsdatei eingerichtet haben, suchen Sie einfach diese Datei nach stdio. Wenn eine Kompilierungseinheit direkt oder indirekt stdio.h enthält, wird sie in der Abhängigkeitsdatei aufgeführt.

+0

Das Problem mit grepping so (abgesehen davon, dass ich die Makefiles, die ich lieber vermeiden würde, weil sie durch einen anderen Prozess generiert werden, nicht mehr), ist das dann Sie haben Sorgen wie was ist, wenn es in einem Kommentar ist, was ist, wenn es # ifdef'd out und nicht anwendbar ist, etc. Es gibt einige Drittanbieter-Dateien, die .c sind, die ihre eigenen Debug-Modus Flags getrennt haben, so würde es müssen Ausnahmelisten sein, etc ... – HostileFork

+0

Angesichts einer Auswahl von "invasive" auf einem Makefile und "Invasions" auf allen Kompilierungseinheiten (auch bekannt als Quelldateien) in einem Projekt, würde ich die erste wählen. Selbst in einem komplexen Projekt übersteigt die Anzahl der Makefiles selten die Anzahl der Kompilierungseinheiten. Es gibt Techniken, um die benutzerdefinierte Handhabung in automatisch generierten Makefiles zu gewährleisten, indem make rekursiv usw. verwendet wird. – Peter

+0

Vernünftig und danke für die Option upvoted. Aber für meinen speziellen Fall ist die bessere Wahl in der Balance, Makefiles nicht zu berühren ... – HostileFork

Verwandte Themen