2017-11-24 14 views
2

Ich arbeite an etwas Geometrie-basierten Code. Die vorliegende Aufgabe beinhaltet die Verwendung einer Begrenzungsbox zur Aufnahme der festen Probe. Nun, im Code habe ich zwei verschiedene Arten solcher Boxen entwickelt, nämlich INNER_BOUNDING_BOX und OUTER_BOUNDING_BOX. Der Code erwartet außerdem die Verwendung eines der beiden Felder, aber nicht beide. Ich versuche es mit dem Präprozessor zu erreichen. Ich habe weiteren Code basierend auf ein paar Makros geschrieben, nämlich USE_INNER_BOUNDING_BOX und USE_OUTER_BOUNDING_BOX.Bedingte Makrodefinition zur Emulation default define

#if defined(USE_INNER_BOUNDING_BOX) && defined(USE_OUTER_BOUNDING_BOX) 
    #undef USE_INNER_BOUNDING_BOX 
    #undef USE_OUTER_BOUNDING_BOX 
    #define USE_INNER_BOUNDING_BOX 
#endif 

#ifndef USE_INNER_BOUNDING_BOX 
    #ifndef USE_OUTER_BOUNDING_BOX 
     #define USE_INNER_BOUNDING_BOX 
    #endif 
#endif 

Nun, wenn ich eine bestimmte Box verwenden wollte, könnte ich definiere nur das entsprechende Makro: Ich kann durch einiges einfaches Konstrukt wie dies jederzeit ein Makro definiert ist sicherzustellen, dass. Die Schwierigkeit kommt mit Wollen für die Verwendung eines Standard-Einstellung Makro sagen USE_DEFAULT_BOUNDING_BOX, die ich verwenden könnte, um dann definieren für eine der USE_INNER_BOUNDING_BOX oder USE_OUTER_BOUNDING_BOX, wenn beide oder keine von ihnen explizit definiert sind. Ich würde zu tragbarem Code neigen, aber Compiler-spezifischen Trick könnte auch passieren. Ich benutze Visual Studio 2012.

+1

Nicht wirklich eine Antwort auf die Frage, die Sie stellen, aber warum definieren Sie nicht einen einzigen Schalter 'BOUNDING_BOX_TO_USE' zu' INNER == 1' 'OUTER == 2'? So könnte es inhärent nicht beides sein. – Yunnosch

+0

Ich könnte etwas ähnliches schreiben. Es hat mir damals nicht geschmerzt. :) Ich werde versuchen, es vielleicht anders umzusetzen. Es ist jedoch immer noch eine zufällige Frage und es hat Spaß gemacht, fragte ich. :) – user2338150

+0

Diese Makroblöcke machen schon genau das, was Sie wollen: Definieren Sie eines dieser Makros, wenn entweder beide oder keines davon definiert ist. Es könnte aber auch kürzer sein. – VTT

Antwort

1

Zuverlässige one-of-viele Auswahlmöglichkeiten, wie sie besser kann durch die Wahl sie mit einem einzigen Mehrwertschalter sofort erfolgen.

#define BOUNDING_INNER 1 
#define BOUNDING_OUTER 2 

/* default */ 
#define BOUNDING_BOX_TO_USE BOUNDING_INNER 

/* alternatively please activate below line 
#define BOUNDING_BOX_TO_USE BOUNDING_OUTER 
*/ 

Wenn Sie zu einigen Konfigurationen rückwärtskompatibel bleiben müssen,
z.B. Ihr Code wurde bereits von anderen verwendet,
Sie können den einzelnen Schalter von den beiden ableiten und Ihr Standardverhalten anpassen. Der Vorteil ist zu vermeiden #undef (falls Sie zustimmen, dass es ein Vorteil ist, dies zu tun).

#if defined(USE_INNER_BOUNDING_BOX) && defined(USE_OUTER_BOUNDING_BOX) 
#define BOUNDING_BOX_TO_USE BOUNDING_INNER 
#endif 

#ifndef USE_INNER_BOUNDING_BOX 
    #ifndef USE_OUTER_BOUNDING_BOX 
     #define BOUNDING_BOX_TO_USE BOUNDING_INNER 
    #endif 
#endif 

/* In case you are as paranoid a programmer as I am, 
    you might want to do some plausibility checking 
    here. ifndef, >0, <2 etc., triggering some #errors. */ 


/* Later, in code doing the actual implementation: */ 

#if (BOUNDING_BOX_TO_USE == BOUNDING_INNER) 
/* do inner bounding stuff */ 
#endif 
/* other code, e.g. common for inner and outer */ 
#if (BOUNDING_BOX_TO_USE == BOUNDING_OUTER) 
/* do outer bounding stuff */ 
#endif 
+0

Ich nehme es als Antwort. Ich sollte stattdessen USE_OUTER_BOUNDING_BOX oder USE_INNER_BOUNDING_BOX in den equals-Blöcken definieren und dieselben in vorherigen Blöcken durch etwas anderes ersetzen. Ja, ich würde gerne so bleiben, wie sie waren, und Undefs vermeiden. Ist das nicht eine gute Übung im allgemeinen Sinn, damit Sie sich nicht in Konflikten zwischen unzusammenhängenden, unwissenden Teilen des Codes befinden? – user2338150

+0

Ich glaube, ich verstehe nicht wirklich, um was für eine Übung es sich handelt. Verwenden undef? Nicht gut meiner Meinung nach. Rückwärts kompatibel zu bereits verteilten Konfigurationskonzepten bleiben? Gut meiner Meinung nach. Konflikte klären? Gut. Undeks loswerden, um dies zu tun? Gut. – Yunnosch

+1

Ja, und Sie verpasst definiert von IDE oder Projekt-Dateien, Makefiles. Entschuldigung, ich musste mitten im Gespräch gehen. Wie auch immer, ich denke, ich könnte einige der Probleme der Code-Compilation teilen, die du anscheinend durchgemacht hast. Willst du paranoid sein, ich wünschte, ich könnte anders denken. – user2338150

0

Da es nur zwei Werte würde ich nur eine Boolesche Variable verwenden:

#ifndef USE_OUTER_BOUNDING_BOX 
    #define USE_OUTER_BOUNDING_BOX 0 
#endif 

Wenn USE_OUTER_BOUNDING_BOX Null ist (falsch) die innere Begrenzungsrahmen verwendet wird.

test.c:

#include <stdio.h> 

#ifndef USE_OUTER_BOUNDING_BOX 
    #define USE_OUTER_BOUNDING_BOX 0 
#endif 

int main(void) 
{ 
    printf("%d\n", USE_OUTER_BOUNDING_BOX); 
    return 0; 
} 

Beispiel:

$ cc -o test -DUSE_OUTER_BOUNDING_BOX=0 test.c 
$ ./test 
0 
$ cc -o test -DUSE_OUTER_BOUNDING_BOX=1 test.c 
$ ./test 
1 
+0

In diesem Fall würde es sicherlich funktionieren, aber die Frage war, nach einem Overkill-Preprozessor-Trick zu suchen, der funktionieren würde, wenn mehr als zwei Boxen beteiligt wären. Ich hätte die Frage so formulieren sollen. Wie auch immer, Ihr Code würde auch in meinem Fall funktionieren, aber er benötigt eine Abhängigkeit vom Wert des Makros, den ich nicht explizit spezifizieren möchte. Ich habe diese schnelle Lösung hier gefunden.Natürlich müsste es für mehr Box-Typen (die bedingten Blöcke) geändert werden: – user2338150

0

Hier ist, was ich mit endete:

// Comment to use bigger outer Bounding-Box 
#define USE_INNER_BOUNDING_BOX 

#define INNER_BOUNDING_BOX 0 
#define OUTER_BOUNDING_BOX 1 

#define DEFAULT_BOUNDING_BOX OUTER_BOUNDING_BOX 

#if defined(USE_INNER_BOUNDING_BOX) && !defined(USE_OUTER_BOUNDING_BOX) 
    #define USE_BOUNDING_BOX INNER_BOUNDING_BOX 
#elif defined(USE_OUTER_BOUNDING_BOX) 
    #define USE_BOUNDING_BOX OUTER_BOUNDING_BOX 
#else 
    #define USE_BOUNDING_BOX DEFAULT_BOUNDING_BOX 
#endif 

#if (USE_BOUNDING_BOX == INNER_BOUNDING_BOX) 
    #undef USE_OUTER_BOUNDING_BOX 
    #define USE_INNER_BOUNDING_BOX 
#else 
    #undef USE_INNER_BOUNDING_BOX 
    #define USE_OUTER_BOUNDING_BOX 
#endif 

Dies funktioniert nur in diesem Fall. Im Falle von mehr Boxen würde ich die bedingten Blöcke anhängen.