「最初の試行」はコンパイルされませんが、2番目の試行はコンパイルされます。どうして?違いは何ですか?
最初の試み:
#include <iostream>
int main()
{
constexpr const char text2[] = "hello";
constexpr const char * b = &text2[4]; // error: '& text2[4]' is not a constant expression
std::cout << b << std::endl;
}
2回目の試行:
#include <iostream>
int main()
{
constexpr const char * text1 = "hello";
constexpr const char * a = &text1[4];
std::cout << a << std::endl;
return 0;
}
(g ++バージョン4.9.2)でコンパイルします
g++ -std=c++11 -o main *.cpp
次のエラーが発生します
main.cpp: In function 'int main()':
main.cpp:7:40: error: '& text2[4]' is not a constant expression constexpr const char * b = &text2[4]; // error: '& text2[4]' is not a constant expression
ドラフトC++ 11標準セクション5.19
[expr.const]から、 アドレス定数式 is(強調鉱山ゴングフォワード):
[...] prvalueコア定数式静的ストレージ期間を持つオブジェクトのアドレスに評価されるポインター型、関数のアドレス、またはnullポインター値、またはprvalue std :: nullptr_t型のコア定数式。
最初のケースでは、"hello"
は静的な保存期間を持つ文字列リテラルですが、静的ストレージ期間のない配列text2
にコピーされます。
2番目のケースでは、text1
は静的な保存期間を持つ 文字列リテラル へのポインタです。
最初の例を変更してtext2
を静的(ライブで参照):
constexpr char static text2[] = "hello";
^^^^^^
エラーが発生しなくなりました。
セクション2.14.5
[Lex.string]から、文字列リテラルに静的な保存期間があることがわかります。
通常の文字列リテラルおよびUTF-8文字列リテラルは、ナロー文字列リテラルとも呼ばれます。狭い文字列リテラルのタイプは「arrayofn const char」です。ここで、nは以下に定義する文字列のサイズであり、静的ストレージ期間(3.7)があります。