命令:显示当前编辑器的认知复杂性 象征: 功能 :该命令启动静态代码分析,并计算当前编辑器中代码认知复杂度的测量值。打开的对话框会显示结果并在标题中指定测量值总和。列出并显示分析的代码以及检测到的复杂性。 称呼 : 构建 → 静态分析 菜单 要求 :在编辑器中打开 ST 实现语言的编程对象。 对话框:<POU 名称> 的认知复杂性:<计算的测量值> 例 13 . 例子 本节内容如下 :
SA0011:只有一个成员的无用声明 检测仅具有单个成员的结构或枚举 理由:不应声明只有一个成员的结构或枚举。此类声明可能会让读者感到困惑。只有一个元素的结构可以用别名类型替换。只有一个元素的枚举可以用常量替换。 PLCopen规则:CP22/CP24 重要性:低 例 22 . 例子 {attribute 'qualified_only'} {attribute 'strict'} TYPE SI
SA0014:实例分配 检测功能块实例的分配。在具有指针或引用变量的实例的情况下,这些赋值具有潜在的风险。 理由:这是一个性能警告。当一个实例分配给另一个实例时,所有元素和子元素都从一个实例复制到另一个实例。指向数据的指针也会被复制,但不会复制它们引用的数据,因此目标实例和源实例在赋值后包含相同的数据。根据实例的大小,这种分配可能会持续很长时间。例如,如果应该将一个实例传递给一个函数进行处理,那么
SA0016:结构中的间隙 检测由当前设置的目标系统的对齐要求引起的结构或功能块中的间隙。如果可能,您应该通过使用结构元素或用虚拟元素填充它们来消除间隙。如果这是不可能的,那么您可以通过以下方式停用受影响结构的规则 analysis 语用。 说明:由于不同平台的对齐要求不同,这些结构在内存中可能会有不同的布局。然后代码可以根据平台执行不同的操作。 重要性:低 例 28 . 例子 TYPE Unpa
SA0021:传输临时变量的地址 检测临时变量(在堆栈上)到非临时变量的地址分配 理由:函数或方法的局部变量是在堆栈上创建的,它们仅在处理函数或方法时才存在。如果一个指针在处理完方法或函数后指向这种变量,那么你可以使用这个指针访问未定义的内存,或者访问另一个函数中不正确的变量。应不惜一切代价避免这种情况。 重要性:高 例 32 . 例子 FUNCTION TempVarInFUNC : DWORD
SA0022:(可能)未分配的返回值 检测所有包含执行线程但未分配返回值的函数和方法 理由:函数或方法中未分配的返回值表示缺少代码。即使返回值总是有一个默认值,再次显式分配它以避免混淆总是有用的。 重要性:中等 例 33 . 例子 FUNCTION FUN : DINT VAR_INPUT bTest : BOOL; END_VAR IF bTest THEN RETURN; END_IF FUN
SA0001:无法访问的代码 检测未执行的代码行,例如由于 RETURN 或者 CONTINUE 陈述 理由:应始终避免无法访问的代码。这 测试 通常表明测试代码仍然存在,应该删除。 重要性:高 PLCopen 规则:CP2 例 14 . 例子 PROGRAM PLC_PRG VAR xReturn_Before_End: BOOL; xContinue_In_Loop_FUN: BOOL; iC
SA0003:空语句 检测带有分号 ( ; ) 但不是声明 理由:空语句可能是缺少代码的标志。 注意:使用空语句有充分的理由。例如,在一个 CASE 声明明确地编程出所有情况是有意义的,即使是那些无事可做的情况。当这种空 CASE 语句包含注释,静态分析不会生成错误消息。 重要性:低 例 15 . 例子 CASE value OF 1: DoSomething(); 2: ; 3: DoSomet
SA0004:输出上的多写访问 检测写入多个位置的输出。 理由:当输出写入代码的不同位置时,可维护性会降低。然后不确定哪个写访问是在该过程中实际产生影响的访问。好的做法是计算辅助变量中的输出变量,并在循环结束时将计算值分配到一个位置。 重要性:高 PLCopen规则:CP12 提示 当输出变量 ( VAR_IN_OUT ) 被写入不同的分支 IF 和 CASE 陈述。 杂注不能禁用此规则。 例 1
SA0008:检查子范围类型 检测超出范围的子范围类型违规。编译器已经检查了分配的文字。分配常量时,值必须在定义的范围内。分配变量时,数据类型必须相同。 说明:如果使用子范围类型,则确保不退出此子范围。编译器仅针对常量分配检查这些类型的子范围违规。 重要性:低 提示 不对 CFC 对象执行检查,因为代码结构不允许这样做。 例 19 . 例子 VAR_GLOBAL iVarGlob:INT; END