■sizeof演算子は関数ではない
sizeof演算子を関数だと思っている人は結構多く、
この人達は
【sizeofの戻り値】って書くのだけれど、
1+1の戻り値って言わないですよね。
聖典プログラミング言語C
A7.4.8 sizeof演算子では
【結果(result)】という表現を使ってます。
なので、
【sizeofの戻り値】ではなくて
【sizeofの結果】と書こう。
■sizeof演算子とstrlen関数の違い
#include <stdio.h>
#include <string.h>
int main(void){
char ary[1024] = "123";
printf("%zu\n",strlen(ary));//文字列の長さ:3
printf("%zu\n",sizeof(ary));//配列のサイズ:1024
char *ptr = "123";
printf("%zu\n",strlen(ptr));//ポインタの指す先の文字列の長さ:3
printf("%zu\n",sizeof(ptr));//ポインタのサイズ:LP64=8,ILP32=4
}
●Linux64bit(LP64)モードでの実行結果
■sizeof(sizeof(…))
warning: suspicious usage of ‘sizeof(sizeof(…))’
警告:’sizeof(sizeof(…))’ の疑わしい使用法。
[misc-sizeof-expression]
#include <string.h>
void f(int ary[],int num){
memset(ary,0,sizeof(num * sizeof(int)));
}
sizeofの中にsizeofがあります。
やりたい事が
int型の配列をnum個0クリアしたい場合
memset(ary,0,sizeof(num * sizeof(int)));
ではなくて
memset(ary,0,num * sizeof(int));
のはずです。
■sizeof*sizeof
(warning): Multiplying sizeof() with sizeof() indicates a logic error.
警告:sizeof()とsizeof()の掛け算は多分間違い
[(warning)multiplySizeof]
#include <string.h>
void NG(void){
char buf[1024];
memset(buf,0,sizeof(char)*sizeof(buf));//ダメ
}
1個のサイズ X 全体のサイズ
= 算数的に意味がない
1個のサイズ X 全体の要素数
= 全体のサイズ
➡修正例
#include <string.h>
void OK(void){
char buf[1024];
memset(buf,0,sizeof(buf)); //良い
}
void OKOK(void){
char buf[1024]={0};//とても良い
}
■sizeof(定数)
(warning) Suspicious usage of ‘sizeof’ with a numeric constant as parameter.
警告:sizeof(定数)
[(warning)sizeofwithnumericparameter]
#include <string.h>
int main(void)
{
char buf[1024];
memset(buf,0,sizeof(1024));
}
この間違いをあなたはどのように
修正しますか?
memset(buf,0,sizeof(1024));//間違いの例
修正案1:memset(buf,0,1024);
修正案2:memset(buf,0,sizeof(buf));
修正案3:memset(buf,0,sizeof(char)*1024);
修正案4:char buf[1024]={0};
この問題はgccやclangでは見つけてくれません。
cppcheckと言う無料ツールが見つけてくれます。
■sizeof(配列[定数])
void f(void)
{
char buf[1024];
memset(buf,0,sizeof(buf[1024]));
}
似たような間違いで
1024byte全部クリアしたいようですが、
1byteしかクリアしません。
この問題を見つけるツールは今のところ知りません。
参考: