基本的に、はい、静的であるため、値が無期限に続くという意味で安全です。
定数データへの変数ポインターではなく、変数データへの定数ポインターを返したという意味では安全ではありません。呼び出し元の関数がデータを変更することを許可しない方がよいでしょう:
const char *GetString(void)
{
static char sTest[5];
strncpy(sTest, "Test", sizeof(sTest)-1);
sTest[sizeof(sTest)-1] = '\0';
return sTest;
}
示されている単純なケースでは、バッファ オーバーフローを心配する必要はほとんどありませんが、コードの私のバージョンは心配し、null 終了を保証します。代わりに、 TR24731関数を使用することもできます。strcpy_s
const char *GetString(void)
{
static char sTest[5];
strcpy_s(sTest, sizeof(sTest), "Test");
return sTest;
}
さらに重要なことは、両方のバリアントが定数データへの (変数) ポインターを返すため、ユーザーは文字列を変更したり、(おそらく) 配列の範囲外を踏みつぶしたりしないでください。(@strager がコメントで指摘しているように、a を返すことconst char *
は、ユーザーが返されたデータを変更しようとしないことを保証するものではありません。ただし、返されたポインターをキャストして非定数にしてからデータを変更する必要があります。これは未定義の動作を引き起こし、その時点で何でも可能です。)
リテラル戻り値の利点の 1 つは、通常、コンパイラとオペレーティング システムによって書き込み禁止の約束を強制できることです。文字列はプログラムのテキスト (コード) セグメントに配置され、戻り値が指すデータをユーザーが変更しようとすると、オペレーティング システムはエラー (Unix ではセグメンテーション違反) を生成します。
[他の回答の少なくとも 1 つは、コードが再入可能ではないことを示しています。それは正しいです。リテラルを返すバージョンは再入可能です。再入可能性が重要な場合は、呼び出し元がデータを格納するスペースを提供できるようにインターフェイスを修正する必要があります。]