我们最近发现了一行代码,它的作用相当于
bool should_escape_control_char(char ch) {
return (ch < 0x20); // control chars are 0x00 through 0x1F
}
这个作品如果平原 char
未签名 ;但如果简单 char
已签名,则此过滤器也会意外捕获负字符。 (最终的结果是一个简单的 JSON 编码器将 "é"
编码为 "\u00c3\u00a9"
因为对于编码器来说,它看起来像一对负字符,然后单独编码。)IMO,这里的原罪是我们正在比较一个普通的
char
针对整数的表达式,其结果取决于 char
的符号性.我希望编译器告诉我们:fantasy-warning: this comparison's result may depend on the signedness of plain char
return (ch < 0x20); // control chars are 0x00 through 0x1F
^~~~~~~~~
fantasy-note: cast the operand to silence this diagnostic
return (ch < 0x20); // control chars are 0x00 through 0x1F
~~
(signed char)(ch)
我惊讶地发现 Clang 在这种情况下没有提供警告选项;而且我在 GCC 中也没有看到任何警告选项。最佳答案
即使您将代码更改为
bool should_escape_control_char(unsigned char ch)
因为您仍在对平台上的字符编码做出假设。用int std::iscntrl( int ch );
取而代之,或 C 等价物,具体取决于您使用的语言。引用 https://en.cppreference.com/w/cpp/string/byte/iscntrl
(可以从该站点访问 C 版本)。
关于c++ - 由于纯字符签名,哪些工具可以诊断 C++ 可移植性问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66281057/