在代码分析期间,PVS-Studio分析数据流并操作变量值。 值取自常量或条件表达式。 我们称它们为虚拟价值。 最近,我们对它们进行了细化以与多字符常量一起使用,这已成为创建新诊断规则的原因。
引言
多字符字面量是
实现定义的 ,因此不同的编译器可以用不同的方式对其进行编码。 例如,GCC和Clang根据文字中符号的顺序设置一个值,而MSVC根据符号的类型(常规或转义)移动它们。
例如,“ T \ x65s \ x74”文字将以不同的方式进行编码,具体取决于编译器。 分析仪中必须添加类似的逻辑。 结果,我们创建了一个新的诊断规则V1039来识别代码中的此类文字。 这些文字在使用多个编译器进行构建的跨平台项目中很危险。
诊断V1039
让我们来看一个例子。 下面的代码由不同的编译器编译,其行为将有所不同:
#include <stdio.h> void foo(int c) { if (c == 'T\x65s\x74') // <= V1039 { printf("Compiled with GCC or Clang.\n"); } else { printf("It's another compiler (for example, MSVC).\n"); } } int main(int argc, char** argv) { foo('Test'); return 0; }
该程序由不同的编译器编译,将在屏幕上打印不同的消息。
对于使用特定编译器的项目,它不会引起注意。 但是在移植时,可能会出现问题,因此应使用简单的数字常量替换此类文字,例如将“ Test”更改为0x54657374。
为了演示编译器之间的区别,我们将编写一个小的实用程序,该程序使用3和4个符号的序列,例如'GHIJ'和'GHI',并在编译后在内存中显示它们的表示形式。
实用代码:
#include <stdio.h> typedef int char_t; void PrintBytes(const char* format, char_t lit) { printf("%20s : ", format); const unsigned char *ptr = (const unsigned char*)&lit; for (int i = sizeof(lit); i--;) { printf("%c", *ptr++); } putchar('\n'); } int main(int argc, char** argv) { printf("Hex codes are: G(%02X) H(%02X) I(%02X) J(%02X)\n",'G','H','I','J'); PrintBytes("'GHIJ'", 'GHIJ'); PrintBytes("'\\x47\\x48\\x49\\x4A'", '\x47\x48\x49\x4A'); PrintBytes("'G\\x48\\x49\\x4A'", 'G\x48\x49\x4A'); PrintBytes("'GH\\x49\\x4A'", 'GH\x49\x4A'); PrintBytes("'G\\x48I\\x4A'", 'G\x48I\x4A'); PrintBytes("'GHI\\x4A'", 'GHI\x4A'); PrintBytes("'GHI'", 'GHI'); PrintBytes("'\\x47\\x48\\x49'", '\x47\x48\x49'); PrintBytes("'GH\\x49'", 'GH\x49'); PrintBytes("'\\x47H\\x49'", '\x47H\x49'); PrintBytes("'\\x47HI'", '\x47HI'); return 0; }
该实用程序的输出,由Visual C ++编译:
Hex codes are: G(47) H(48) I(49) J(4A) 'GHIJ' : JIHG '\x47\x48\x49\x4A' : GHIJ 'G\x48\x49\x4A' : HGIJ 'GH\x49\x4A' : JIHG 'G\x48I\x4A' : JIHG 'GHI\x4A' : JIHG 'GHI' : IHG '\x47\x48\x49' : GHI 'GH\x49' : IHG '\x47H\x49' : HGI '\x47HI' : IHG
该实用程序的输出,由GCC或Clang编译:
Hex codes are: G(47) H(48) I(49) J(4A) 'GHIJ' : JIHG '\x47\x48\x49\x4A' : JIHG 'G\x48\x49\x4A' : JIHG 'GH\x49\x4A' : JIHG 'G\x48I\x4A' : JIHG 'GHI\x4A' : JIHG 'GHI' : IHG '\x47\x48\x49' : IHG 'GH\x49' : IHG '\x47H\x49' : IHG '\x47HI' : IHG
结论
在最近发布的
7.03版PVS-Studio分析仪中添加了V1039诊断。 您可以在
下载页面上
下载最新版本的分析仪。