Pourquoi le caractère «A» serait-il comparé à 0x41?

89

Je regardais du code C ++ et j'ai trouvé la construction suivante:

if('A' == 0x41) {
  // ...
} else if('A' == 0xc1) {
  // ...
} else {
  // ...
}

Je reçois un avertissement Visual Studio disant:

Avertissement L'expression conditionnelle C4127 est constante.

Visual Studio a clairement raison - sûrement «A» est défini comme 0x41. Pourquoi l'auteur écrit-il ce code, étant donné que deux des trois branches sont du code mort?

H Bellamy
la source
30
Ce ne sont pas nécessairement du code mort, c'est peut-être juste un moyen stupide de vérifier le jeu de caractères.
George
60
'A' = C1 dans EBCDIC
harold
14
Je le mettrais dans un en-tête utilitaire comme #define IS_CHSET_EBCDIC ('A' == 0xc1)etc .; ou, en C ++ moderne, en faire un constexpr.
Peter - Réintègre Monica
8
@ b.buchhold - Non, vous pouvez effectuer une compilation croisée d'un PC vers le mainframe. Ainsi, «A» doit signifier la valeur du caractère dans le jeu de caractères d'exécution.
Bo Persson
2
Il semble que cela soit mieux fait en utilisant l'inclusion conditionnelle du préprocesseur (par exemple #if 'a' == 41 ... #else ... #endif) pour faire cela plutôt que des branches dynamiques afin de ne pas recevoir d'avertissements comme ceux-ci . Cela fonctionnerait-il?
templatetypedef

Réponses:

116

0xc1est le EBCDICcode de jeu de caractères pour A. L'auteur teste une telle machine.

http://www.ibm.com/support/knowledgecenter/en/SSGH4D_15.1.3/com.ibm.xlf1513.aix.doc/language_ref/asciit.html

Richard Hodges
la source
14
"y a-t-il un meilleur moyen que celui-ci pour vérifier le jeu de caractères?" Il n'y a pas de moyen standard de le faire. En C11, il existe un moyen de vérifier si certains encodages Unicode sont utilisés, mais MSVC ne supportera même pas entièrement C99 (qui est antérieur à C11). "Quelle est la fréquence de ce jeu de caractères alternatif!" Outre les mainframes IBM? Pas du tout.
2
Alors, à quoi sert la dernière elsebranche? Existe-t-il un encodage de caractères encore utilisé qui n'est compatible ni avec ASCII ni avec EBCDIC?
dan04
8
@ dan04 Aucun à ma connaissance, mais cela pourrait être aussi simple qu'une branche "encodage inconnu, message d'erreur d'impression".
8
«A» est également 0xC1 dans le codage de caractères Apple II DOS 3.3, qui est ASCII OU avec 0x80.
Damian Yerrick
2
@Rhymoid Il y a en fait de bonnes chances que Microsoft implémente C11 avant de prendre en charge C99. Ils faisaient partie des fournisseurs qui ont repoussé les fonctionnalités C99 difficiles à implémenter, dont deux ne sont plus obligatoires dans C11 en.wikipedia.org/wiki/… .
Steve Cox
11

À première vue, cela pourrait ressembler à du code mort, mais 'A' == 0x41 ne retournera pas toujours vrai.

ce que le développeur a essayé de faire ici est de trouver paresseusement quel encodage est la machine implémentant ASCII ou toute variante d' EBCDIC

comme @Richard l'a suggéré, Capital a est mappé à 0xc1 dans le code d'échange décimal codé binaire international étendu, voir le tableau ci-dessous dans la branche 2 de if else ...

entrez la description de l'image ici

une autre valeur différente pourrait être trouvée par ASCII par exemple:

entrez la description de l'image ici

il aurait aussi bien pu faire:

if('p' == 0x70) {
  // ...
} else if('p' == 0x97) {
  //...
}
ΦXocę 웃 Пepeúpa ツ
la source
Dans le deuxième paragraphe - vouliez-vous dire EBCDIC au lieu d'EBDIC?
Zze