2012-11-09 16 views
5

ビットシフトとマスキング演算の使用のためにコンパイル時に生成される定数が必要な場合がよくあります。コンパイラ前処理​​中の数学演算

#define blockbits 8 
#define blocksize 256 // could be generated from 2^blockbits 
#define blocksize 0xFF // could be generated from blocksize - 1 

私はこれらすべてが​​3210から生成されたい、しかし、私が知っプリプロセッサで使用することができる無電力動作はありません。

誰もコンパイル時にこのようなことを生成する簡単な方法を知っていますか?

+0

"しかし、私が知っているプリプロセッサで使用できるパワー操作はありません。" - 本当ですか?ビットシフトはどうですか? –

+2

これはC++だから、定数ではなく '#define'の理由は何ですか? – Kos

+0

これは 'constexpr'の仕事ではありませんか? – DavidO

答えて

8

あなたは数学的な表現としてそれらを定義することができます。

#define blockbits 8 
#define blocksize (1 << blockbits) 
#define blockXXXX (blocksize - 1) // changed from blocksize to blockXXXX, since blocksize is already taken 

括弧を使用すると、他の式でそれらを使用するときに何の演算子の優先順位の問題がないことを確認することです。

BLOCKBITS,BLOCKSIZEなどの名前をすべて大文字に変更することもできます。これは、マクロを通常の名前と区別するためのC++命名規則です。

+2

+1とすると、プリプロセッサはそのままで置き換え、コンパイラは値を計算します。 – Kos

0

#defineの代わりにconstを使いたい場合や、実行時に値を計算する汎用の力関数(2の累乗だけでなく)を作成したい場合は、次のようなテンプレートを使って試してみることもできます:

template<int num, int pow> struct temp_pow 
{ 
    static const unsigned int result=temp_pow<num, pow-1>::result*num; 
}; 

template<int num> struct temp_pow<num, 1> 
{ 
    static const unsigned int result=num; 
}; 

const int BLOCKBITS = 8; 
const int BLOCKSIZE = temp_pow<2,BLOCKBITS>::result; // could be generated from 2^BLOCKBITS 
const int BLOCKSIZE_1 = BLOCKSIZE-1;