Edited at

C/C++で使える定数について

More than 3 years have passed since last update.

C/C++では定数を定義するためのいくつかの異なる方法がある。

方法
コンパイル時定数?
アドレス取得可能?
その他

const

Y

static const

Y

constexpr
Y
Y
C++11から

#define

N
単純置換
型無し

enum
Y
N
整数定数のみ
内部型は実装依存(※)

(※) enumはC++11から内部で使用する整数型を自分で決められるようになった。


コンパイル時定数?

コンパイル時定数でないと、テンプレートパラメータや配列宣言時の要素数指定として使えない。

conststatic const#defineはどのように初期化・宣言するかによってコンパイル時定数かどうかが異なる。

// f() は定数表現でないものとする

const int a = f(); // OK コンパイル時定数ではない
static const int b = f(); // OK コンパイル時定数ではない
constexpr int c = f(); // NG 定数表現でしか初期化できない
#define d f() // OK コンパイル時定数ではない
enum { e = f() }; // NG 整数定数表現でしか初期化できない

しかし、この3つもリテラルなどの定数表現で初期化・宣言すればコンパイル時定数として扱える。

確実にコンパイル時定数であることが保証されるのはconstexprenumだけである。


アドレス取得可能?

変数はアドレスを持っているものだが、#defineenumは変数ではないから、アドレスを持たない。