2016-07-15 5 views
6

マクロ展開:C私は、コンパイル時のデフォルト値で配列を埋めるために使用するマクロを繰り返すマクロを持っているため

const int array [512] = 
{ 
    MACRO_REPEAT(512, -2) // this repeats -2, 512 times 
    [4] = 10, 
    [5] = 2, 
    ... 
} 

マクロの繰り返しがMACRO_REPEAT_512に展開されますが、今、私は他のマクロを使用していました配列のサイズとして、のように:

#define ARRAY_LENGTH 512 
const int array [ARRAY_LENGTH ] = 
{ 
    MACRO_REPEAT(ARRAY_LENGTH , -2) // this repeats -2, 512 times 
    [4] = 10, 
    [5] = 2, 
    ... 
} 

しかし、これはMACRO_REPEAT_ARRAY_LENGTHに展開、それを連結する前にARRAY_LENGTH値を展開しません。これはMARO_REPEAT_X * Yに拡大する

#define X 512 
#define Y 512 

const int array [X][Y] = 
{ 
    MACRO_REPEAT(X*Y , -2) // this repeats -2, 512 times 
    [4] = 10, 
    [5] = 2, 
    ... 
} 

:他の例では、拡張のより多くのレベルを含む多次元配列のためであろう。ですから、それらの値を他のマクロに連結する前に最後の数値に展開する方法はありますか?

+0

単純にループや 'memset()'を使うのはなぜですか?はい、実行時には動作しますが、比較的簡単に目的の効果を達成できます。 – Peter

+2

GCCには、 'int array [ARRAY_LENGTH] = {[0 ... 3] = -2、[4] = 10、[5] =など、同じ値に要素の範囲を初期化できる拡張があります。 2、[6 ... ARRAY_LENGTH-1] = -2、}; ' –

+1

@Peter私は知っているが、私は組み込みシステムで作業していて、これをフラッシュに保存したいと思っている(const qualifierで更新された質問) – rnunes

答えて

1

MACRO_REPEATの定義を2段階の拡張を使用するように変更して解決することができます。すなわち、MACRO_REPEAT自体にトークンペーストを使用せず、別のマクロを呼び出します。

ARRAY_LENGTHが単一の数値トークンとして定義されている場合、およびこの特定のサイズのマクロ定義がある場合、これは期待どおりに機能しません。

より一般的なMACRO_REPEAT(X*Y , -2)ケースを標準のCプリプロセッサで処理することはできません。

#define MACRO_REPEAT(n, e) [ 0 ... (n)-1 ] = (e), 

をしかし、この方法は、そのようなMACRO_REPEAT(X*Y , -2)として多次元配列を処理するために使用することはできません。

あなたは単純な配列を初期化するためにgccの拡張機能を使用することができます。

#define MACRO_REPEAT(n, e) [ 0 ... (n)-1 ] = (e), 
#define X 512 
#define Y 512 

const int array[X][Y] = { MACRO_REPEAT(X, { MACRO_REPEAT(Y, -2) }) }; 

をしかし、Cプリプロセッサの使用は、単に意図を難読化:

あなたはこれを試みることができます。 gcc拡張に依存することに決めた場合は、それらを直接使用してください。

+0

私は知っていますが、X列とY列を持つ多次元配列は、X * Y単一次元配列を見る別の方法です。私はあなたがint array [1] [2] = {first、second}のようなものをやることができると信じています。最初は[0] [0]に格納され、もう1つは[0] [1]に格納されます。 – rnunes

+0

@munes: :262144のイニシャライザのシーケンスにマクロを展開することができれば、それは動作します。あなたの現在のマクロの定義で 'MACRO_REPEAT(512、{MACRO_REPEAT(512、-2)})'を試してください。 – chqrlie

+0

@chqrlieそれはコンパイルされませんhttps://ideone.com/1GQf9N – 4pie0

1

OPの質問に直接答えることはできないため、「正しい」答えとしてカウントされるかどうかはわかりませんが、問題の推奨される回避策です。 GCCエクステンションを使用するため、標準C言語でもありません。

GNU Cコンパイラ(gcc)では、配列要素の範囲は、[FIRST ... LAST] = VALUEの形式で同じ値に初期化できます。また、要素に複数の指定イニシャライザを許可するように見えるので、同じ値に要素の範囲を初期化して異なる値にその範囲内に含まれる要素を初期化することが可能であり、このような何か:

#define ARRAY_LENGTH 512 
const int array[ARRAY_LENGTH] = 
{ 
    [0 ... ARRAY_LENGTH - 1] = -2, 
    [4] = 10, 
    [5] = 2, 
    /* ... */ 
}; 
+0

あなたが知っているのは、元の質問に対する答えではないことです(あなたはそれがもっと広くなったと思います)。再投稿のリクエストについて申し訳ありませんが、chqrlieは正しい答えに近いと答えます – rnunes

関連する問題