次のコードがあります。
#include <stdlib.h>
#include <stdio.h>
void test(unsigned char * arg) { }
int main() {
char *pc = (char *) malloc(1);
unsigned char *pcu = (unsigned char *) malloc(1);
*pcu = *pc = -1; /* line 10 */
if (*pc == *pcu) puts("equal"); else puts("not equal"); /* line 12 */
pcu = pc; /* line 14 */
if (pcu == pc) { /* line 16 */
test(pc); /* line 18 */
}
return 0;
}
オプション付きのgccバージョン4.6.3(Ubuntu / Linaro 4.6.3-1ubuntu5)(ただし、この特定のバージョンに限定されません)でコンパイルした場合
gcc a.c -pedantic -Wall -Wextra -Wsign-conversion -Wno-unused-parameter; ./a.out
次の警告が表示されます
test.c: In function ‘main’:
test.c:10:21: warning: conversion to ‘unsigned char’ from ‘char’ may change the sign of the result [-Wsign-conversion]
test.c:14:13: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
test.c:16:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
test.c:18:17: warning: pointer targets in passing argument 1 of ‘test’ differ in signedness [-Wpointer-sign]
test.c:4:6: note: expected ‘unsigned char *’ but argument is of type ‘char *’
not equal
g++ の警告/エラーも同様です。12行目の比較がfalseと評価される理由を理解していただければ幸いですが、そのような場合でも警告を表示する方法はありますか? そうでない場合、12行目と警告の原因となる行との間に主な違いはありますか? char と unsigned char の比較が警告に値しない特定の理由はありますか? 少なくとも一見すると、12行目は16行目などよりも「危険」に見えるからです。
短い「裏話」: さまざまなソースからのコードをまとめる必要があります。char を使用するものもあれば、unsigned char を使用するものもあります。-funsigned-char
正常に動作しますが、それを避け、適切な型変換を追加する必要があります。そのような場合に型変換を追加するのを忘れると、プログラムは暗黙のうちに失敗するため、このような警告が役立つのはそのためです。
よろしくお願いします、P.