SA0072:计数器变量的无效使用 检测计数器变量的使用 FOR 环形 理由:在 a 中操作计数器变量 FOR 循环很容易导致无限循环。要防止针对计数器变量的特定值执行循环,请使用 CONTINUE 或者只是一个 IF 。 重要性:高 PLCopen 规则:L12 例 79 . 例子 PROGRAM PLC_PRG VAR_TEMP iIndex : INT; END_VAR FOR iIndex
SA0076: 缺少枚举常量 确定每个枚举常量是否用作条件 CASE 语句并在 a 中查询 CASE 分支。 理由:防御性编程需要处理枚举的所有可能值。如果特定枚举值不需要执行操作,则应添加注释以明确指出这一点。然后,代码的读者很清楚,该值并没有被简单地遗忘。 重要性:低 例 82 . 例子 TYPE My_Enum : ( red := 1, blue := 2, green := 3, bla
SA0081:上边界不是常数 检测到 FOR 未使用常量值定义上限的语句 理由:如果循环的上限是一个变量值,那么就不再可能看到循环执行的频率。这可能会导致运行时出现严重问题。最坏的情况是无限循环。 重要性:高 例 85 . 例子 PROGRAM PLC_PRG VAR i:INT; iBorder1: INT := 10; iBorder2: INT := 10; iCounter: INT; E
SA0090:函数结束前的 RETURN 语句 检测代码位置 RETURN 语句不是函数、方法、属性或程序中的最后一个语句。地点 RETURN 存在于一个 IF 还检测到分支。 理由:A RETURN 在代码中导致代码的可维护性、可测试性和可读性变差。一个 RETURN 在代码中很容易被忽略。每次之前 RETURN ,经常忘记插入退出函数时应始终执行的代码。 重要性:中等 PLCopen规则:CP
SA0053:按位移位太大 在操作数按位移位(bit shift)的情况下,检测是否超出了操作数的数据类型宽度 理由:如果移位操作超出数据类型宽度,则为常数 0 生成。 如果旋转移位超过数据类型宽度,则难以读取。因此,应缩短旋转值。 重要性:高 例 62 . 例子 PROGRAM PLC_PRG VAR byTemp1 : BYTE; wTemp2 : WORD; dwTemp3 : DWORD;
SA0055:无符号操作数的不必要比较 检测与无符号操作数的不必要比较。无符号数据类型永远不会小于零。这可以用作符号检查。 理由:使用此检查检测到的比较会产生恒定的结果,并且表明代码中存在错误。 重要性:高 例 64 . 例子 PROGRAM PLC_PRG VAR byTest: BYTE; END_VAR // SA0055 WHILE byTest >= 0 DO byTest := byT
SA0062:在表达式中使用 TRUE 或 FALSE 检测文字的使用 TRUE 或者 FALSE 在表达式中 理由:布尔文字的运算 TRUE 或者 FALSE 应避免重复计算并每次返回相同的结果。这种表达是多余的,应该被替换。它的存在表明存在错误。无论如何,表达式都会不必要地增加程序运行时的负担。 重要性:中等 例 72 . 例子 PROGRAM PLC_PRG VAR xTemp1, xTem
SA0019:隐式指针转换 检测隐式生成的指针转换 理由:在 CODESYS ,指针没有严格类型化,它们可以以任何方式相互赋值。这经常被使用,因此编译器不会报告。但是,它也可能意外地导致意外访问。如果您指定一个 POINTER TO BYTE 到一个 POINTER TO DWORD ,那么您可能会无意中使用后一个指针覆盖内存。因此,请务必检查此规则,并在您故意想要访问不同类型的值的情况下阻止该消
SA0130:隐式扩展转换 检测算术运算期间隐式执行从较小数据类型到较大数据类型的转换的代码位置 理由:当源类型的值范围完全包含在目标类型的值范围内时,编译器允许不同类型的任何赋值。但是,编译器将尽可能晚地构建对代码的转换。对于类型的赋值 lint := dint * dint ,编译器仅在乘法之后执行隐式转换: lint := TO_LINT(dint * dint); 因此溢出被截断。如果你想
SA0133:显式缩小转换 检测从较大数据类型到较小数据类型的显式转换 理由:大量类型转换可能表明您为变量选择了错误的数据类型。因此,有一些编程指南要求对数据类型转换提供明确的理由。 重要性:低 例 55 . 例子 PROGRAM SA0133 VAR siVar:SINT; diVar:DINT; liVar:LINT; byVar:BYTE; uiVar:UINT; dwVar:DWORD;