【C言語】
文字列の型と符号付き/符号なしcharの違い
(警告対策と適切な型の選び方)

warning: pointer targets in passing argument 1 of ‘strcpy’ differ in signedness

警告: ‘strcpy’ の第一引数は符号が異なる
[-Wpointer-sign]


■この記事の概要

この記事では、C言語における文字列の扱い方と、符号付き・符号なしchar型に関する警告の原因を解説します。

具体例を用い、型の違いによって生じる警告メッセージを防ぐ方法を示し、キャストの推奨・非推奨を考察します。

最適なプログラミング手法として、型の見直しや必要最低限のキャストを推奨し、外部インタフェースとの互換性についても説明します。

■型が違うと警告される例

#include    <string.h>
typedef unsigned char   UB ;
struct  ctsk {
    //外部インタフェースで決まっている
    UB dsname[8];
} x ;
void    f(UB   *dsname)
{    
    strcpy(x.dsname,dsname);//型が違うと怒られる
}
int main(void)
{
    f("dsname");//型が違うと怒られる
}

文字列の型はchar *型ですが
unsigned char *型(UB*型)で引数を
受け渡しているため型が違うと
コンパイラに怒られます。

以下の三つの型は独立した別の型なので
混在するとコンパイラから型が違うと怒られます。
(1) char
(2) signed char
(3) unsigned char

※注意
(1)のcharは
(2)のsigned charや
(3)のunsigned charの
省略形ではない事に注意して下さい。

■✖ コンパイラが黙るまでキャスト

void    f(UB   *dsname)
{    
    strcpy((char *)x.dsname,(char *)dsname);//キャスト
}
int main(void)
{
    f((UB *)"dsname");//キャスト
}

非推奨です。

■○ 型を見直し必要最低限のキャスト

void    f(char *dsname)//型の見直し
{   
    strcpy((char *)x.dsname,dsname);//必要最低限のキャスト
}
int main(void)
{
    f("dsname");
}

型を見直し素直にchar *を使う。

外部インタフェースの制限で変更できない場合は、
必要最低限のキャストをする。


参考:

STR04-C. 基本文字集合にある文字を表すには単なる char を使用する

https://www.jpcert.or.jp/sc-rules/c-str04-c.html