60 votes

Avertissements constants à plusieurs caractères

Pourquoi est-ce un avertissement ? Je pense qu'il y a de nombreux cas où il est plus clair d'utiliser des constantes int à plusieurs caractères plutôt que des nombres "sans signification" ou plutôt que de définir des variables constantes avec la même valeur. Lors de l'analyse de fichiers wave/tiff/autres types de fichiers, il est plus clair de comparer les valeurs lues avec des 'EVAW', 'data', etc. au lieu de leurs valeurs correspondantes.

Exemple de code :

int waveHeader = 'EVAW';

Pourquoi cela donne-t-il un avertissement ?

59voto

Selon la norme (§6.4.4.4/10)

La valeur d'une constante de caractère entière contenant plus d'un caractère (par exemple, 'ab'), [...] est définie par l'implémentation. caractère (par exemple, 'ab'), [...] est définie par l'implémentation.

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

Il s'agit de la norme ISO 9899:2011 C valide. Elle se compile sans avertissement sous gcc con -Wall et un avertissement "constante de caractère à plusieurs caractères" avec -pedantic .

De Wikipedia :

Les constantes à plusieurs caractères (par exemple 'xy') sont valables, bien que rarement utiles. utiles - elles permettent de stocker plusieurs caractères dans un nombre entier (par ex. ASCII peuvent tenir dans un entier de 32 bits, 8 dans un entier de 64 bits). Puisque l'ordre dans lequel les caractères sont emballés dans un int n'est pas n'est pas spécifié, l'utilisation portable des constantes à plusieurs caractères est difficile.

Pour des raisons de portabilité, n'utilisez pas de constantes à plusieurs caractères avec des types intégraux.

26voto

Didier Trosset Points 17949

Cet avertissement est utile pour les programmeurs qui écriraient par erreur 'test' où ils auraient dû écrire "test" .

Cela arrive beaucoup plus souvent que les programmeurs qui veulent réellement des constantes int à plusieurs caractères.

18voto

blueshift Points 3281

Si vous êtes sûr de savoir ce que vous faites et que vous pouvez accepter les problèmes de portabilité, sur GCC par exemple, vous pouvez désactiver l'avertissement sur la ligne de commande :

-Wno-multichar

Je l'utilise dans mes propres applications pour travailler avec les en-têtes de fichiers AVI et MP4 pour des raisons similaires aux vôtres.

8voto

Ivan Points 16

La solution C/C++ la plus simple, conforme à tout compilateur/standard, a été mentionnée par @leftaroundabout dans les commentaires ci-dessus :

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

Ou un peu plus spécifique :

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

Une autre solution, également conforme au compilateur/standard C/C++ depuis C99 (à l'exception de clang++, qui a un bug connu ) :

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, l'union anonyme est utilisée pour donner un joli nom-symbole au résultat numérique souhaité, la chaîne "abcd" est utilisée pour initialiser la valeur l de la fonction littéral composé (C99).

8voto

o11c Points 1687

Même si vous êtes prêt à chercher le comportement que votre implémentation définit, les constantes à plusieurs caractères vont toujours varient avec l'endiveté.

Il vaut mieux utiliser une (POD) struct { char[4] } ; ... et ensuite utiliser un UDL comme "WAVE"_4cc pour construire facilement des instances de cette classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X