warning: cast from pointer to integer of different size
警告:ポインタ型を型幅の違う整数型にキャストした
[-Wpointer-to-int-cast]
■memset(buf,(int)NULL,sizeof(buf));
#include <stdio.h>
#include <string.h>
void f1(void){
char buf[1024];
memset(buf,(int)NULL,sizeof(buf));//NG
}
「0 はマジックナンバーなので使用禁止!」と
教育された初級者が
0と書けず
NULLと書き、
コンパイラに警告されて (int)NULL とキャストする場合が多いです。
●memset(buf,0,sizeof(buf));
void f2(void){
char buf[1024];
memset(buf,0,sizeof(buf));//OK
}
0はマジックナンバーではないので素直にべたで0と書く。

■for(p = s; *p != (char)NULL; p++)
size_t f3_strlen(char *s)
{
char *p;
for (p = s; *p != (char)NULL; p++)//NG
;
return p - s;
}
「文字列の最後にはNULL文字がある」と教育された初級者が
‘\0’と書かずに
NULLと書き、
コンパイラに警告されてキャストする場合が多いです。
●for (p = s; *p != ‘\0’; p++)
size_t f4_strlen(char *s)
{
char *p;
for (p = s; *p != '\0'; p++)//OK
;
return p - s;
}
「文字列の最後には終端文字’\0′がある」と教育しましょう。

■問題:文字列にキャストすると?
warning: suspicious usage of ‘sizeof(A*)’; pointer to aggregate
警告:余計なキャストが疑わしい
[misc-sizeof-expression]
問題:次のプログラムは何と表示されるでしょうか?
#include <stdio.h>
#include <string.h>
#define STRING (const char *)"123456789abcdef"
int main(void)
{
printf("%ld\n",sizeof( "123456789abcdef"));
printf("%ld\n",sizeof((char *)"123456789abcdef"));
printf("%ld\n",sizeof(STRING));
printf("%ld\n",strlen(STRING));
}
sizeof((char *)“123456789abcdef”)は余計なキャストをしているため、文字列リテラル”123456789abcdef”は無視され
sizeof(char *)と同じ結果が求まります。
sizeof(STRING)も同様ですが、
キャストがマクロで隠されるのでより問題の発見が難しくなります。
●解答

■不要なキャストは読みにくい
warning: redundant cast to the same type
警告:冗長キャスト
[google-readability-casting]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *cp = (char *)malloc(sizeof(char)*(int)1024);
if((char *)cp == (char *)NULL){
printf("メモリ確保失敗\n");
return (int)1;
}
memset((void *)cp,(int)'\0',sizeof(char)*1024);
strncpy((char *)cp,(const char *)"a-b-c",(int)6);
char *sp = strchr((char *)cp,(int)'-');
if((char *)sp == (char *)NULL){
printf((const char *)"'-'検索失敗\n");
return (int)1;
}
printf((const char *)"%s\n",(char *)sp);
if((char *)cp != (char *)NULL){
free((void *)cp);
}
return (int)0;
}
●例1:malloc()/free()にキャストしたがる理由
C-FAQ7.7
http://www.kouno.jp/home/c_faq/c7.html#7
MEM02-C. Immediately cast the result of a memory allocation function call into a pointer to the allocated type
ここの末尾のコメント欄の議論が面白い
●例2:NULLにキャストしたがる理由
NULLについて
http://f4.aaacafe.ne.jp/~pointc/log1018.html
●例3:文字定数にキャストしたがる理由
推測⇒
C言語では文字定数がint型だと知らないから
int型に明示的にキャストする?
●例4:memset/cpy/cmpの引数にキャストしたがる理由
推測⇒
K&Rという初代C言語では汎用ポインタの void * がなく
char *で代用していた大昔の習慣が現代に継承されている?

■不要なキャストを削除すると読みやすい
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *cp = malloc(1024);
if(cp == NULL){
printf("メモリ確保失敗\n");
return 1;
}
memset(cp,'\0',1024);
strcpy(cp,"a-b-c");
char *sp = strchr(cp,'-');
if(sp == NULL){
printf("'-'検索失敗\n");
free(cp);
return 1;
}
printf("%s\n",sp);
free(cp);
}
冗長を削除した推奨する修正例