いくつかの文字列リテラルで初期化された多次元C文字列配列を定義したいと思います。ではC Iは、次の操作を行います:
#include <stdio.h>
const char *strArr[2][1] = { {"foo"}, {""}};
int main(void) {
printf("%p\t%p\n", strArr[0][0], strArr[1][0]);
return 0;
}
gcc -std=c18 -pedantic test.c
結果をコンパイルして実行すると、次のようになります。
$ ./a.out
0x55d95410f004 0x55d95410f008
予想どおり、空の文字列リテラルはstrArr[1][0]
有効なポインタに減衰します。
しかし、私は同じコードを試してみてくださいC ++:
#include <cstdio>
const char *strArr[2][1] = { {"foo"}, {""}};
int main(void) {
printf("%p\t%p\n", strArr[0][0], strArr[1][0]);
return 0;
}
g++ -std=c++17 -pedantic test.cpp
結果をコンパイルして実行すると、次のようになります。
$ ./a.out
0x55c61494d004 (nil)
ここでは、空の文字列リテラルはstrArr[1][0]
nullポインターに減衰します。これはなぜC ++で起こるのですか?
C ++ 17標準では、5.13.5の段落16に次のように表示されます。
通常の文字列リテラルおよびUTF-8文字列リテラルは、ナロー文字列リテラルとも呼ばれます。ナロー文字列リテラルのタイプは「n const charの配列」で、nは以下で定義する文字列のサイズで、静的な保存期間(6.7)を持っています。
これは、空の文字列リテラルが通常の文字列リテラルであるため、静的な保存期間が必要であることを示しているようです。では、なぜ空の文字列リテラルがnullポインタに減衰するのでしょうか。
@super空の文字列には、ターミネーターという1つの文字があります。印刷すると、何も出力されません。
—
Weather Vane
これはおそらくGCC 9の退行です。あなたはそれを報告し、彼らが言うことを見るべきです。
—
ブライアン、
g ++はこれを行いますが、clangは行いません:gcc.godbolt.org/z/XkZcVy g ++バグのように見えます。
—
PSkocik
GCC bugzillaサイトでの@KeithThompsonアカウントの作成は制限されているので、明日までに完了すると期待されるメールリクエストを送信しました。今のところ、Gentooのバグレポートを開いています
—
Vilhelm Grey
std::array
?