Pourquoi est-ce un avertissement? Je pense qu'il y a de nombreux cas où il est plus clair d'utiliser des constantes multi-char int au lieu de nombres "sans signification" ou au lieu de définir des variables const avec la même valeur. Lors de l'analyse syntaxique des types de fichiers wave/tiff/autres, il est plus clair de comparer les valeurs lues avec certains "EVAW", "données", etc. au lieu de leurs valeurs correspondantes.
Exemple de code:
int waveHeader = 'EVAW';
Pourquoi cela donne-t-il un avertissement?
Selon la norme (§6.4.4.4/10)
La valeur d'une constante de caractère entier contenant plus d'un caractère (par exemple, 'ab'), [...] est définie par l'implémentation.
long x = '\xde\xad\xbe\xef'; // yes, single quotes
Ceci est valide ISO 9899: 2011 C. Il se compile sans avertissement sous gcc
avec -Wall
, et un avertissement de "constante de caractères multi-caractères" avec -pedantic
.
De Wikipedia :
Les constantes à plusieurs caractères (par exemple 'xy') sont valides, bien que rarement utiles - elles permettent de stocker plusieurs caractères dans un entier (par exemple 4 ASCII peuvent tenir dans un entier 32 bits, 8 dans un 64 bits). Étant donné que l'ordre dans lequel les caractères sont regroupés dans un entier n'est pas spécifié, l'utilisation portable de constantes à plusieurs caractères est difficile.
Pour des raisons de portabilité, n'utilisez pas de constantes à plusieurs caractères avec des types intégraux.
Cet avertissement est utile pour les programmeurs qui écriraient par erreur 'test'
où ils auraient dû écrire "test"
.
Cela se produit beaucoup plus souvent que les programmeurs qui souhaitent réellement des constantes multi-caractères.
Si vous êtes heureux de savoir ce que vous faites et pouvez accepter les problèmes de portabilité, sur GCC par exemple, vous pouvez désactiver l'avertissement sur la ligne de commande:
-Wno-multichar
J'utilise cela pour mes propres applications pour travailler avec les en-têtes de fichiers AVI et MP4 pour des raisons similaires à vous.
Même si vous êtes prêt à rechercher le comportement défini par votre implémentation, les constantes multi-caractères varieront en fonction de l'endianité.
Mieux vaut utiliser une structure (POD) {char [4]}; ... puis utilisez un UDL comme "WAVE" _4cc pour construire facilement des instances de cette classe
La solution la plus simple compatible C/C++ avec tout compilateur/standard a été mentionnée par @leftaroundabout dans les commentaires ci-dessus:
int x = *(int*)"abcd";
Ou un peu plus précis:
int x = *(int32_t*)"abcd";
Une autre solution, également compatible avec tout compilateur/standard C/C++ (sauf clang ++, qui a un bug conn ):
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");
Ici, le littéral de chaîne "abcd" est converti en tableau, puis l'union anonyme est utilisée pour donner un nom de symbole Nice au résultat numérique souhaité.