【C言語】
sizeof演算子のよくある間違い!sizeofは関数ではない

sizeof()は関数ではない

■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)モードでの実行結果

3
1024
3
8

■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)));
}

やりたい事が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));//ダメ
}

一個のサイズ X 全体のサイズ = 算数的に意味がない
一個のサイズ X 全体の要素数 = 全体のサイズ


➡sizeof*sizeof

#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しかクリアしません。
この問題を見つけるツールは今のところ知りません。