wake-up-neo.com

Warnungen, die aus mehreren Zeichen bestehen

Warum ist das eine Warnung? Ich denke, es gibt viele Fälle, in denen es klarer ist, Int-Konstanten mit mehreren Zeichen anstelle von "No Meaning" -Zahlen zu verwenden oder stattdessen konstante Variablen mit demselben Wert zu definieren. Beim Parsen von Wave-/TIFF-/anderen Dateitypen ist es klarer, die gelesenen Werte mit einigen 'EVAW'-,' Daten'-Werten usw. zu vergleichen, anstatt mit den entsprechenden Werten.

Beispielcode:

int waveHeader = 'EVAW';

Warum gibt dies eine Warnung?

33
Felics

Gemäß der Norm (§6.4.4.4/10)

Der Wert einer Ganzzahl-Zeichenkonstante, die mehr als ein Zeichen enthält (z. B. 'ab'), [...] ist implementierungsdefiniert.

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

Dies ist die gültige ISO 9899: 2011 C. Sie kompiliert ohne Warnung unter gcc mit -Wall Und mit -pedantic Als Warnung vor einer Konstante aus mehreren Zeichen.

Aus Wikipedia :

Konstanten mit mehreren Zeichen (z. B. 'xy') sind gültig, aber selten nützlich. Sie ermöglichen das Speichern mehrerer Zeichen in einer Ganzzahl (z. B. 4 ASCII Zeichen können in eine 32-Bit-Ganzzahl passen, 8) Da die Reihenfolge, in der die Zeichen in ein int gepackt werden, nicht angegeben ist, ist die übertragbare Verwendung von Konstanten mit mehreren Zeichen schwierig.

Verwenden Sie aus Gründen der Portabilität keine Konstanten mit mehreren Zeichen und ganzzahligen Typen.

36
user195488

Diese Warnung ist nützlich für Programmierer, die fälschlicherweise 'test' wo sie hätten schreiben sollen "test".

Dies passiert viel häufiger als bei Programmierern, die tatsächlich Int-Konstanten mit mehreren Zeichen wollen.

14
Didier Trosset

Wenn Sie zufrieden sind, wissen Sie, was Sie tun, und können die Portabilitätsprobleme akzeptieren. In GCC können Sie beispielsweise die Warnung in der Befehlszeile deaktivieren:

-Wno-multichar

Ich verwende dies für meine eigenen Apps, um aus ähnlichen Gründen wie Sie mit AVI- und MP4-Dateiköpfen zu arbeiten.

13
blueshift

Auch wenn Sie bereit sind, nachzuschlagen, welches Verhalten Ihre Implementierung definiert, variieren die Konstanten mit mehreren Zeichen immer noch je nach Endianness.

Besser eine (POD) Struktur verwenden {char [4]}; ... und verwenden Sie dann eine UDL wie "WAVE" _4cc, um auf einfache Weise Instanzen dieser Klasse zu erstellen

4
o11c

Die einfachste C/C++ - Lösung, die mit Compilern/Standards kompatibel ist, wurde von @leftaroundabout in den obigen Kommentaren erwähnt:

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

Oder etwas genauer:

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

Eine weitere Lösung, die auch mit jedem C/C++ - Compiler/-Standard kompatibel ist (mit Ausnahme von clang ++, das hat einen bekannten Fehler ):

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");

Hier wird das Zeichenfolgenliteral "abcd" in ein Array umgewandelt. Anschließend wird eine anonyme Vereinigung verwendet, um dem gewünschten numerischen Ergebnis einen Nizza-Symbolnamen zu geben.

2
sqr163