「C++ プログラミング言語第 4 版」という本を読みながら、アドレス定数式について掘り下げています。アドレス定数式を説明する短い段落があります。
グローバル変数など、静的に割り当てられたオブジェクトのアドレスは定数です。ただし、その値はコンパイラではなくリンカーによって割り当てられるため、コンパイラはそのようなアドレス定数の値を知ることができません。これにより、ポインターと参照型の定数式の範囲が制限されます。例えば:
constexpr const char* p1 = "asdf"; constexpr const char* p2 = p1; //OK constexpr const char* p2 = p1+2; //error: the compiler does not know the value of p1 constexpr char c = p1[2]; //OK, c=='d'; the compiler knows the value pointed to by p1
2 つの質問があります。
これはかなり些細なことです。コンパイラは静的オブジェクトのアドレスを知らないため、コンパイル時に 2 番目のステートメントをどのように評価できるのでしょうか。結局、コンパイラが の値を知らないという事実は、そもそもそれが不明でなければならない
p1+2
ことを意味しp1
ますよね? ただし、すべての厳格なフラグがオンになっている g++ 4.8.1 は、これらすべてのステートメントを受け入れます。このトピックで例示されているように:
static constexpr int N = 3; int main() { constexpr const int *NP = &N; return 0; }
ここで、NP はアドレス定数式、つまりそれ自体が定数式であるポインタとして宣言されています。(これは、静的/グローバル定数式にアドレス演算子を適用してアドレスを生成する場合に可能です。)
N
これは、単純const
に withoutとして宣言した場合にも機能しconstexpr
ます。ただし、有効なステートメントであるためには、p1
を使用して明示的に宣言する必要があります。それ以外の場合は次のようになります。constexpr
p2
エラー: 'p1' の値は定数式では使用できません
何故ですか?"asdf"
私のconst char[]
知る限りです。