为什么将字符“ A”与0x41进行比较?


89

我正在查看一些C ++代码,发现以下结构:

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

我收到Visual Studio警告,说:

警告C4127条件表达式恒定。

Visual Studio显然是正确的-肯定将“ A”定义为0x41。鉴于三个分支中有两个是无效代码,为什么作者要编写此代码?


30
它们不一定是无效代码,也许这只是检查字符集的一种愚蠢方法。
乔治,

60
EBCDIC中的'A'= C1
哈罗德

14
我会将其放在实用程序标头中,#define IS_CHSET_EBCDIC ('A' == 0xc1)以此类推;或者,在现代C ++中,将其设为constexpr
彼得-恢复莫妮卡

8
@ b.buchhold-不,您可以从PC交叉编译到大型机。因此,“ A”必须表示执行字符集中的字符值。
Bo Persson

2
似乎最好使用预处理器条件包含(例如#if'a'== 41 ... #else ... #endif)来执行此操作,而不要使用动态分支,这样您就不会收到此类警告。那行得通吗?
templatetypedef

Answers:


116

14
“有没有比这更好的方法来检查字符集了?” 没有标准的方法可以这样做。在C11中,有一种方法可以检查是否正在使用某些Unicode编码,但是MSVC甚至不会完全支持C99(早于C11)。“这种备用字符集有多普遍!” 除了IBM大型机?一点也不。

2
那么最后的else分支是做什么的呢?是否仍在使用与ASCII或EBCDIC都不兼容的字符编码?
dan04

8
@ dan04我所不知道的,但是实际上它可以像“未知编码,打印错误消息”分支一样简单。

8
在Apple II DOS 3.3字符编码中,“ A”也是0xC1,它与0x80进行ASCII或运算。
Damian Yerrick '16

2
@Rhymoid实际上,Microsoft很有可能会在支持C99之前实施C11。他们是拒绝实施难以实现的C99功能的供应商之一,其中两个不再在C11en.wikipedia.org/wiki/…中是必需的。
史蒂夫·考克斯

11

乍一看可能看起来像是死代码,但“ A” == 0x41并非总是会返回true。

开发人员试图在这里懒惰地发现实现ASCIIEBCDIC的任何变体的机器是什么编码

正如@Richard建议的那样,大写字母a已映射到国际-扩展二进制编码的十进制交换码中的0xc1, 请参见if if else的2分支中的下表...

在此处输入图片说明

ASCII可以找到另一个不同的值,例如:

在此处输入图片说明

他也可以做​​到:

if('p' == 0x70) {
  // ...
} else if('p' == 0x97) {
  //...
}

在第二段中,您是说EBCDIC而不是EBDIC吗?
Zze
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.