2010-03-31 54 views
9

雖然聽上去荒謬.....你可以讓增量編譯器常量?

我想爲常數,且每次使用它時,它將由1

int x; 
int y; 
x = INCREMENTING_CONSTANT; 
y = INCREMENTING_CONSTANT; 

增加,其中x == 1;和y == 2

注意我不想要y = INCREMENTING_CONSTANT + 1類型的解決方案。

基本上我想使用它作爲一個編譯時唯一的ID(通常它不會在代碼中使用類似的例子,但裏面另一個宏)

+0

由於該變量是基於編譯器的,因此我們需要知道您正在討論哪個編譯器。 – 2010-03-31 22:55:31

+0

交叉編譯器......理想情況下,它將在至少3個編譯器上使用。 – 2010-03-31 22:57:58

+0

這實際上是重複http://stackoverflow.com/questions/2076757/incremented-define但解決方案是爲C++,但會看到我是否可以使用相同的技術C – 2010-03-31 23:05:42

回答

-1

好吧,它不是常量,那麼,是什麼呢? ;)

您可以用功能做到這一點:

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

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

如圖所示,這是不是線程安全的。要做到這一點,你需要用互斥體保護這個,或者使用編譯器/平臺特定的原子增量器。

+0

以及編譯時間常量:)這是你的答案完全失敗! :) 因此我的問題,如何使增量編譯時間不斷!非常像____LINE____根據你所在的代碼行而改變:) – 2010-03-31 22:53:03

+1

我不認爲這是他想要的。這將在每次調用函數時在運行時生成一個新值。我想他希望在編譯時計算一次該值,然後每次運行該行時使用相同的值。 – 2010-03-31 22:53:27

-2

「遞增常數」是一個矛盾。你不能在編譯時做到這一點。

+2

看起來像一個,但「常量」部分是指在編譯時而不是符號不變。 – 2010-03-31 22:59:33

+2

其實它有很多不變的值,每一個都大於前面的那個 – 2010-04-01 08:02:30

7

您可以使用Boost.Preprocessor(含C工作)和BOOST_PP_COUNTER

例的docs頁上給出裝上去在一起:

#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 

翻譯成你想要

#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 
什麼

您也可以使用插槽(以比上述解決方案更多的代碼爲代價,稍微更靈活):

#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

如果您只是需要一些獨特的ID ISH,您可以使用__LINE__預處理器符號?這不是你要求的,但它可能適用於你的目的。

+0

同意,我總是使用'​​__LINE__'來表示我看到'__COUNTER__'使用的相同類型的東西。 – 2010-03-31 23:31:32

+0

__LINE__是我想離開使用 – 2010-04-01 01:40:09

1

我經常希望編譯時變量。然而,最簡單的事情就是爲每個單獨定義常量。

在我的線程問題上面的答案可以通過在某些全局狀態類或類似的解決方案中使用函數類來解決,如果您使用C而不是C++。

你也可以嘗試使用xmacro。創建一個新的文件,我們稱之爲xmacro.h

INCREMENTING_CONSTANT; 
#define INCREMENTING_CONSTANT INCREMENTING_CONSTANT + 1 

然後,在一個標準的頭,

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

const int x = USE_INCREMENTING_CONSTANT 

我沒有測試過這一點,但xmacros有一些真棒力量,經常宏可以」使用,就像defs/undefs一樣,我的直覺說它應該起作用。預處理器功能強大,但非常笨拙,因此可能會失敗。

+0

這看起來很有前途...... – 2010-03-31 23:07:22

+2

這將不起作用 - 預處理程序不會看到由宏擴展導致的指令。 – caf 2010-04-01 11:04:07

0

你想xy本身是常數嗎?如果是這樣做的最簡單,最乾淨的東西可能是使用匿名枚舉:

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

這意味着你只需要到該列表中添加一個新的名稱,它將被賦予下一個整數值。這是一個很有用的技巧,只要它們不同,你不關心這些值是什麼(運行時以外)。例如,在一個GUI分配標識符來控制的時候,你經常會看到:

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

一些GUI框架提供將產生一個新的(使用內部靜態變量)一GetUserId()函數;但我認爲這發生在運行時。接連看到這麼多的電話也有點乏味。

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

不幸的是,我不能使用枚舉的東西,它的完全未知的可能有多少項。 – 2010-04-01 02:41:19

+0

我不知道爲什麼這是一個問題。爲什麼向枚舉中添加一個新項目比在其他地方添加另一行代碼以將其初始化爲某個常量更困難? – Edmund 2010-04-01 02:50:05

+0

,因爲宏可能出現在代碼中的任何一點。最有可能的將是在一個功能的身體....另一個宏將在另一個函數的主體等等,在許多不同的功能將有任意數量的引用宏。每次出現宏時,我都希望它再次增加1 – 2010-04-01 03:59:05

-3

這是一種難以實現的方法。

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

,這不是一個編譯時間常量,它的運行時間.. – 2010-04-01 01:41:08

2

在我的情況,我想對每個子系統的系統範圍內唯一的關鍵,但子系統的選擇將取決於使用該系統的人。這些需要是8位值,因爲它是針對嵌入式系統的。

這是我想出了剛纔:

#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 

// .... 

的挑戰將是確保該包含在這些塊在每次以相同的順序編帶來鏈。