哪些工具可以诊断由于普通字符符号引起的 C++ 可移植性问题?

Quu*_*one 5 c c++ static-analysis char tool-rec

我们最近发现了一行代码,其作用相当于

\n
bool should_escape_control_char(char ch) {\n    return (ch < 0x20);  // control chars are 0x00 through 0x1F\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果 plainchar未签名,则此方法有效;但如果 plainchar被签名,那么这个过滤器也会意外地捕获负字符。(最终的效果是 na\xc3\xafve JSON 编码器进行编码,"\xc3\xa9"因为"\\u00c3\\u00a9"对于编码器来说,它看起来像一对负字符,然后单独编码。)

\n

IMO,这里的原罪是我们将普通char表达式与整数进行比较,结果取决于 的符号char。我希望编译器告诉我们:

\n
fantasy-warning: this comparison's result may depend on the signedness of plain char\n    return (ch < 0x20);  // control chars are 0x00 through 0x1F\n            ^~~~~~~~~\nfantasy-note: cast the operand to silence this diagnostic\n    return (ch < 0x20);  // control chars are 0x00 through 0x1F\n            ~~\n            (signed char)(ch)\n
Run Code Online (Sandbox Code Playgroud)\n

我惊讶地发现 Clang 在这种情况下没有提供警告选项;我在 GCC 中也没有看到任何警告选项。

\n
    \n
  • 我只是没有找对地方吗?
  • \n
  • 有哪些工具/linter/静态分析器可以这种情况下发出警告?
  • \n
\n

Bat*_*eba 4

即使您将其更改为,您的代码也不可移植

bool should_escape_control_char(unsigned char ch)
Run Code Online (Sandbox Code Playgroud)

因为您仍在对平台上的字符编码进行假设。使用

int std::iscntrl( int ch );
Run Code Online (Sandbox Code Playgroud)

相反,或 C 等效项,具体取决于您使用的语言。

参考https://en.cppreference.com/w/cpp/string/byte/iscntrl

(可以从该站点访问 C 版本)。

  • 从问题中可以清楚地看出OP使用UTF-8编码的字符。`iscntrl` 在这里是错误的选择。值集是固定的,并且不依赖于使用的任何区域设置。 (2认同)