web-dev-qa-db-ja.com

複数文字の一定の警告

なぜこれが警告なのですか? 「意味のない」数字の代わりに、または同じ値でconst変数を定義する代わりに、複数文字のint定数を使用する方が明確な場合が多いと思います。 wave/tiff /その他のファイルタイプの解析がより明確な場合、対応する値の代わりに、読み取り値をいくつかの「EVAW」、「data」などと比較します。

サンプルコード:

int waveHeader = 'EVAW';

なぜこれは警告を出すのですか?

33
Felics

標準による (§6.4.4.4/ 10)

複数の文字を含む整数文字定数の値(例: 'ab')、[...]は実装定義です。

long x = '\xde\xad\xbe\xef'; // yes, single quotes

これは、有効なISO 9899:2011 Cです。gcc-Wallを使用して警告なしでコンパイルし、-pedanticで「マルチ文字定数」警告を使用してコンパイルします。

から ウィキペディア

複数文字の定数(例: 'xy')は有効ですが、ほとんど有用ではありません。複数の文字を整数で保存できます(例:4 ASCII文字は32ビット整数に収まります、8文字が1つのintにパックされる順序が指定されていないため、複数文字の定数を移植して使用することは困難です。

移植性のために、整数型を持つ複数文字の定数を使用しないでください。

36
user195488

この警告は、誤って'test'書かれるべき場所"test"

これは、実際に複数文字のint定数を必要とするプログラマよりも頻繁に発生します。

14
Didier Trosset

自分が何をしているかを知っていて、移植性の問題を受け入れることができて満足している場合、たとえばGCCではコマンドラインで警告を無効にできます。

-Wno-multichar

私はあなたと同じような理由でAVIおよびMP4ファイルヘッダーを操作するために自分のアプリにこれを使用します。

13
blueshift

実装で定義されている動作を検索する場合でも、複数文字の定数はstillエンディアンによって変化します。

(POD)struct {char [4]};を使用する方が良い...そして、「WAVE」_4ccのようなUDLを使用して、そのクラスのインスタンスを簡単に構築します

4
o11c

最も簡単なC/C++コンパイラ/標準準拠ソリューションは、上記のコメントで@leftaroundaboutによって言及されました。

int x = *(int*)"abcd";

またはもう少し具体的に:

int x = *(int32_t*)"abcd";

C/C++コンパイラ/標準に準拠したもう1つのソリューション(clang ++を除く 既知のバグ ):

int x = ((union {char s[5]; int number;}){"abcd"}).number;

/* just a demo check: */
printf("x=%d stored %s byte first\n", x, x==0x61626364 ? "MSB":"LSB");

ここでは、「abcd」文字列リテラルが配列にキャストされ、匿名のユニオンを使用して、目的の数値結果にニースのシンボル名が付けられます。

2
sqr163