2010-03-31 10 views
9

Während unsinnig klingen .....Können Sie einen inkrementierenden Compiler konstant machen?

Ich möchte eine Konstante, wo jedes Mal, wenn Sie es verwenden, es von 1

int x; 
int y; 
x = INCREMENTING_CONSTANT; 
y = INCREMENTING_CONSTANT; 
erhöht wird

wobei x == 1; und y == 2

Hinweis Ich möchte nicht y = INCREMENTING_CONSTANT + 1 Typ Lösungen.

Grundsätzlich mag ich es als eine Kompilierung eindeutige ID verwenden (in der Regel würde es nicht wie das Beispiel in Code verwendet werden, aber in einem anderen Makro)

+0

Da die Variable Compiler basiert, müssen wir wissen, über welchen Compiler Sie sprechen. –

+0

Cross Compiler ... ideal, wie es auf mindestens 3 Compiler verwendet werden wird. –

+0

das dupliziert tatsächlich http://stackoverflow.com/questions/2076757/incremented-define aber die Lösungen sind für C++, aber sehen, wenn ich die gleichen Techniken für C –

Antwort

-1

Nun, es ist nicht konstant, dann ist es? ;)

Sie können mit einer Funktion tun:

int id() { 
    static int i = 0; 
    return ++i; 
} 

x = id(); 
y = id(); 

Wie gezeigt, dies ist nicht Thread-sicher. Um dies zu tun, müssten Sie dies mit einem Mutex schützen oder einen Compiler/Plattform-spezifischen Atom-Inkrementierer verwenden.

+0

gut, kompilieren Zeitkonstante :) wo ist Ihre Antwort vollständig scheitert! :) daher meine Frage, wie man eine inkrementierende Kompilierzeit konstant macht! Ähnlich wie ____LINE____ ändert sich je nachdem, in welcher Zeile des Codes du dich befindest :) –

+1

Ich glaube nicht, dass das genau das ist, was er will. Dies erzeugt zur Laufzeit jedes Mal, wenn die Funktion aufgerufen wird, einen neuen Wert. Ich denke, er möchte, dass der Wert einmal zur Kompilierzeit berechnet wird, dann wird bei jedem Start der Zeile derselbe Wert verwendet. –

-2

Eine "inkrementierende Konstante" ist ein Oxymoron. Sie können dies nicht zur Kompilierzeit tun.

+2

scheint wie eins, aber der "konstante" Teil bezieht sich darauf, zur Kompilierungszeit und nicht zum Symbol konstant zu sein. –

+2

Tatsächlich sind es viele konstante Werte, jeder größer als der vorherige –

7

Sie können in der Lage sein, etwas zusammen zu stellen Boost.Preprocessor mit (Arbeiten mit C) und BOOST_PP_COUNTER

Beispiel gegeben auf der docs Seite:

#include <boost/preprocessor/slot/counter.hpp> 
BOOST_PP_COUNTER // 0 

#include BOOST_PP_UPDATE_COUNTER() 
BOOST_PP_COUNTER // 1 

#include BOOST_PP_UPDATE_COUNTER() 
BOOST_PP_COUNTER // 2 

#include BOOST_PP_UPDATE_COUNTER() 
BOOST_PP_COUNTER // 3 

übersetzt in dem, was Sie wollen

#include <boost/preprocessor/slot/counter.hpp> 

int x = BOOST_PP_COUNTER; // 0 

#include BOOST_PP_UPDATE_COUNTER() 
int y = BOOST_PP_COUNTER;// 1 

#include BOOST_PP_UPDATE_COUNTER() 
int z = BOOST_PP_COUNTER; // 2 

Sie könnten auch Slots (etwas flexibler auf Kosten von mehr Code als die obige Lösung) verwenden:

#include <boost/preprocessor/slot/slot.hpp> 

#define BOOST_PP_VALUE 0 //ensure 0 to start 
#include BOOST_PP_ASSIGN_SLOT(1) 
int a = BOOST_PP_SLOT(1); //0 

#define BOOST_PP_VALUE 1 + BOOST_PP_SLOT(1) 
#include BOOST_PP_ASSIGN_SLOT(1) 
int b = BOOST_PP_SLOT(1); //1 
6

Wenn Sie nur etwas eindeutige ID ish benötigen, können Sie den __LINE__ Präprozessorsymbol verwenden? Es ist nicht das, wonach du verlangst, aber es könnte für deine Zwecke funktionieren.

+0

Zustimmen, ich benutze immer '__LINE__' für die gleichen Dinge, die ich '__COUNTER__' benutze. –

+0

__LINE__ Ist das, was ich weg von der Verwendung –

1

Ich habe oft für die Kompilierzeit Variablen gewünscht. Am einfachsten wäre es jedoch, die Konstanten für jeden einzelnen zu definieren.

Die Antwort über mich Thread-Problem könnte durch die Verwendung eines Funktionaloid in einigen globalen Zustandsklasse oder eine ähnliche Art von Lösung gelöst werden, wenn Sie C und nicht C++ verwenden.

Sie könnten auch versuchen, ein xmacro zu verwenden. Erstellen Sie eine neue Datei, nennen wir es xmacro.h

INCREMENTING_CONSTANT; 
#define INCREMENTING_CONSTANT INCREMENTING_CONSTANT + 1 

Dann wird in einem Standard-Header,

#define INCREMENTING_CONSTANT 0 
#define USE_INCREMENTING_CONSTANT #include "xmacro.h" 

const int x = USE_INCREMENTING_CONSTANT 

Ich habe nicht getestet, aber xmacros haben einige unglaubliche Macht, dass regelmäßige Makros können‘ t verwenden, wie defs/undefs, und mein Bauch sagt, es sollte funktionieren. Der Präprozessor ist leistungsfähig, aber eher dumm, also könnte er fehlschlagen.

+0

verschieben möchte sieht dies vielversprechend .... –

+2

Dies wird nicht funktionieren - der Präprozessor sieht keine Direktiven, die aus Makro-Erweiterung resultieren. – caf

0

Wollen Sie x und y Konstanten selbst sein? Wenn dem so ist die einfachste und sauberste Sache zu tun kann eine anonyme Aufzählung zu verwenden:

enum { 
    x = 1, 
    y 
    /* Add new ones here. */ 
}; 

Das heißt, Sie brauchen nur einen neuen Namen zu dieser Liste hinzuzufügen, und es wird die nächste ganze Zahl angegeben werden. Dies ist ein nützlicher Trick, bei dem es Ihnen egal ist, was die Werte sind (außerhalb der Laufzeit), solange sie sich unterscheiden. Wenn zum Beispiel Kennungen Steuerelemente in einem GUI zuweisen, finden Sie oft:

enum { 
    button1_id = FIRST_USER_ID, 
    button2_id, 
    combo_id, 
    ... 
} 

Einig GUI-Frameworks eine GetUserID() Funktion zur Verfügung stellen, die einen neuen generieren (eine interne statische Variable verwendet wird); aber ich denke, das passiert zur Laufzeit. Es ist auch ein bisschen langweilig, so viele Anrufe nacheinander zu sehen.

button1_id = GetUserId(); 
button2_id = GetUserId(); 
combo_id = GetUserId(); 
... 
+0

leider nein, ich kann das Enum-Ding nicht benutzen, es ist völlig unbekannt, wie viele Artikel es gibt. –

+0

Ich bin mir nicht sicher, warum das ein Problem ist. Warum ist es schwieriger, ein neues Element zu einer Enumeration hinzuzufügen, als es (sagen wir mal) eine andere Codezeile hinzuzufügen, um es an einer anderen Konstante zu initialisieren? – Edmund

+0

, da das Makro an beliebiger Stelle im Code erscheinen kann. Höchstwahrscheinlich wird es im Körper einer Funktion sein ....und ein anderes Makro wäre im Körper einer anderen Funktion usw., es wird eine willkürliche Menge von Verweisen auf das Makro in vielen verschiedenen Funktionen geben. Jedes Mal, wenn das Makro erscheint, möchte ich, dass es wieder um 1 –

-3

Hier ist eine hässliche Art und Weise, sie umzusetzen.

static int _counter=0; 
#define INCREMENTING_CONSTANT (_counter++) 
+2

erhöht, das ist keine Kompilierzeitkonstante, seine Laufzeit. –

2

In meinem Fall wollte ich für jedes Teilsystem einen systemweit eindeutigen Schlüssel haben, aber die Auswahl der Subsysteme auf der Person mit dem System abhängen würde. Diese mussten 8-Bit-Werte sein, da sie auf eingebettete Systeme ausgerichtet sind.

Dies ist, was ich mit gerade jetzt kam:

#define LAST_KEY -1 

// SUB1_KEY definition 
enum { 
    SUB1_KEY_ORIGIN = LAST_KEY, 
    SUB1_KEY, 
}; 
#undef LAST_KEY 
#define LAST_KEY SUB1_KEY 

// SUB2_KEY definition 
enum { 
    SUB2_KEY_ORIGIN = LAST_KEY, 
    SUB2_KEY, 
}; 
#undef LAST_KEY 
#define LAST_KEY SUB2_KEY 

// SUB3_KEY definition 
enum { 
    SUB3_KEY_ORIGIN = LAST_KEY, 
    SUB3_KEY, 
}; 
#undef LAST_KEY 
#define LAST_KEY SUB3_KEY 

// .... 

Die Herausforderung wird sicher sein, machen, dass die Kette enthalten, die in jedem dieser Blöcke bringt jedes Mal in der gleichen Reihenfolge zusammengestellt.

Verwandte Themen