2009-06-10 10 views
1

Angesichts eines C Projekts, das mehrere Umgebungen unterstützen muss, wie verwende ich den Präprozessor, um sicherzustellen, dass genau eine Umgebung definiert ist?Wie erzwinge ich genau eine Definition?

kann ich schon tun:

 
    #if defined PROJA 
    (blah blah blah) 
    #elif defined PROJB 
    (etc) 
    #else 
    #error "No project defined" 
    #endif 

Alles, was der Fall ist, aber ist mir sagen, ob 0 Projekte definiert sind. Wenn eine hilfreiche Seele sowohl Projekt A als auch Projekt B definiert, wird der Präprozessor nur Projekt A annehmen. Das korrekte Verhalten ist jedoch aus meiner Sicht, einen Fehler zu kennzeichnen.

Zugegeben, mit nur 2 Projekten definiert ist dieses Problem trivial. Wie löse ich es mit 200?

+3

mit 200 ein Präprozessor Hack völliger Schmerz zu halten wäre, dann würden Sie lieber den makesystem kümmern brauchen, um diese –

Antwort

2

haben vielleicht verschiedene Dateien

include_proja.h 
include_projc.h 

und dann verwenden Makefile oder was auch immer die richtige Datei aufzunehmen. Sie können dann 200 verschiedene Dateien mit dem Code generieren und die richtigen zur Kompilierungszeit einschließen.

Diese Art der Sache ist, was Build-Systeme für sind. Wenn Sie etwas Seltsames wie dieses mit Makros machen ... finden Sie einen besseren Weg außerhalb des Quellcodes.

kann jede Datei (Entschuldigen Sie die hier Ausführlichkeit) tun

#define A_PROJECT_INCLUDE_WAS_INCLUDED 

Und dann tun

#ifndef A_PROJECT_INCLUDE_WAS_INCLUDED 
    #error "No project include" 
#endif 

Aber einige fehlende Symbole wird es ohnehin in aller Wahrscheinlichkeit brechen.

Good Luck

+1

„Diese Art der Sache ist es, was den Bau von Systemen für sie. Wenn Sie seltsam, etwas zu tun sind so mit Makros ... finde einen besseren Weg außerhalb des Quellcodes. " Sie sind völlig richtig. – JXG

3

etwas wie folgt aus:

#if defined PROJA 
    #ifdef HAVE_PROJ 
    #error 
    #endif 

    #define HAVE_PROJ 
#endif 

#if defined PROJB 
    #ifdef HAVE_PROJ 
    #error 
    #endif 

    #define HAVE_PROJ 
#endif 

#ifndef HAVE_PROJ 
    #error No project selected (you need to define PROJA, PROJB, or ...) 
#endif 
+0

Ich denke, das wird schnell grimmig und ist nicht wirklich etwas, das in Makros imho getan werden sollte. –

0

Das Problem mit verschachtelten ifs ist, dass man mit n^2 verschiedene Tests für n-Projekte am Ende werden.

Sie brauchen nur einen Ausdruck, der in diesem Fall einen Fehler bei der Kompilierung verursacht. Vielleicht:

#ifdef PROJA 
#define PROJA-TEST " 
#else 
#define PROJA-TEST "" 
#endif 

und so weiter für B, C usw.

Dann:

const char *test_only_one_project = PROJA-TEST PROJB-TEST PROJC-TEST " "More than one project is defined!"; 

EDIT: ... Dies ist natürlich nur Tests, die eine ungerade Anzahl von Projekten definiert werden .Aber dies sollte funktionieren:

#ifdef PROJA 
#define PROJA-TEST (
#endif 

und so weiter, dann

const char *test_only_one_project = PROJA-TEST PROJB-TEST PROJC-TEST "More than one project is defined!"); 
+1

Mein erster Gedanke war: "Ja, so würde ich es auch machen." Mein zweiter war: "Ist das der Grund, warum niemand mehr C mag?" –

+0

Genau. Der Präprozessor ist verdammt böse. –

-1

vielleicht kann ich Ihnen so etwas wie:

#if PROJ==A 
(blah blah blah) 
#elif PROJ==B 
(etc) 
#else 
#error "No project defined" 
#endif 
2

Versuchen Sie, diese

#define ENV_UNKNOWN 0 
#define ENV_MACOSX 1 
#define ENV_LINUX 2 
#define ENV_WIN32 3 
/* and so on */ 


#ifndef ENVIRONMENT 
/* no environment given, default to something (perhaps) */ 
#define ENVIRONMENT ENV_UNKNOWN 
#endif 

/* and now the environment specific parts */ 
#if (ENVIRONMENT == ENV_MACOSX) 
#include "macosx_port.h" 
#endif 

#if (ENVIRONMENT == ENV_LINUX) 
#include "linux_port.h" 
#endif 

#if (ENVIRONMENT == ENV_WIN32) 
#include "win32_port.h" 
#endif 

#if (ENVIRONMENT == ENV_UNKNOWN) 
#error You have to specify the ENVIRONMENT. 
#endif 

Jetzt können Sie Geben Sie in der Befehlszeile die Umgebung an, für die Sie kompilieren möchten. dies wie:

cc -DENVIRONMENT=2 ... 

Ein anderer Weg ist, include/verschiedene Module aus dem Build-System verknüpft abhängig von der Umgebung, nach dem Sie kompilieren.

2
#if defined PROJA 
bool one_project_defined = true; 
#endif 

#if defined PROJB 
bool one_project_defined = true; 
#endif 

#if defined PROJC 
bool one_project_defined = true; 
#endif 

#if defined PROJD 
bool one_project_defined = true; 
#endif 

one_project_defined; // Won't compile in wrong builds 
+1

Das ist kurz und einfach. Es fällt mir allerdings als eine Art Hacky auf. – Brian

+0

Bis eine hilfreiche Koop-Person die Wartungsarbeiten erledigt, kommt und denkt: "Hey, diese Variable wird nicht mehr benutzt ..." – David

Verwandte Themen