gcc 4.8 ビルド時にエラーが発生する
#include <string.h>
#include <stdio.h>
static inline void toto(char str[3])
{
snprintf(str, sizeof(str), "XX");
}
int main(){
char str[3];
toto(str);
return 0;
}
ここにgccエラーがあります
エラー: 'snprintf' 呼び出しの 'sizeof' への引数は、宛先と同じ式です。明示的な長さを提供するつもりでしたか?
注: 警告をエラーに変換する -Wall -Werror フラグを使用しています。
ここに似たようなものがあります コメントで、誰かがこれに答えました
「固定長バッファの場合、通常は strncpy(dest, src, sizeof(dest)); dest[sizeof(dest)-1] = '\0'; を使用します。これにより、NULL 終了が保証され、言うまでもなく snprintf よりも手間がかかりません。多くの人が代わりに snprintf(dest, sizeof(dest), src); を使用しており、自分のプログラムが勝手にクラッシュすると非常に驚いています。」
しかし、これは間違っています: gcc 4.8 say
「エラー: 'strncpy' 呼び出しの 'sizeof' への引数は、宛先と同じ式です。明示的な長さを指定するつもりでしたか? [-Werror=sizeof-pointer-memaccess]」
gcc 4.8 ドキュメントでは、彼らはこの問題について話している: 彼らは言う:
-Wall の動作が変更され、新しい警告フラグ -Wsizeof-pointer-memaccess が含まれるようになりました。これにより、以前のバージョンの GCC で正常にコンパイルされたコードで新しい警告が発生する可能性があります。
例えば、
include string.h
struct A { };
int main(void)
{
A obj;
A* p1 = &obj;
A p2[10];
memset(p1, 0, sizeof(p1)); // error
memset(p1, 0, sizeof(*p1)); // ok, dereferenced
memset(p2, 0, sizeof(p2)); // ok, array
return 0;
}
次の診断が表示されます。あなたはそれを逆参照するつもりでしたか?[-Wsizeof-pointer-memaccess] memset(p1, 0, sizeof(p1)); // エラー ^ これらの警告によってコンパイルが失敗することはありませんが、多くの場合、-Wall は -Werror と組み合わせて使用され、その結果、新しい警告が新しいエラーに変わります。修正するには、memcpy を使用するように書き直すか、問題のある memset 呼び出しの最後の引数を逆参照します。*
まあ、彼らの例では、コードが間違っていたことは明らかですが、私の場合、snprintf/strncpy では理由がわかりません。gcc の誤検知エラーだと思います。右 ?
ご協力いただきありがとうございます