SA0011:只有一个成员的无用声明 检测仅具有单个成员的结构或枚举 理由:不应声明只有一个成员的结构或枚举。此类声明可能会让读者感到困惑。只有一个元素的结构可以用别名类型替换。只有一个元素的枚举可以用常量替换。 PLCopen规则:CP22/CP24 重要性:低 例 22 . 例子 {attribute 'qualified_only'} {attribute 'strict'} TYPE SI
SA0012:可以声明为常量的变量 检测未使用写权限访问的变量,因此可以声明为常量 理由:如果变量仅在声明点写入并且仅用于读取,则静态分析假定该变量也不应该被更改。首先,声明为常量会导致检查程序更改时变量是否未更改。其次,声明为常量可能会导致代码更快。 重要 如果一个项目中存在多个应用程序,则仅影响当前活动应用程序下的对象。如果只有一个应用程序,那么公共 POU 池中的对象也会受到影响。 重要性:
SA0013:具有相同变量名的声明 检测名称已被其他变量使用的变量(例如,具有相同名称的全局变量和局部变量)。还可以检测其函数、操作、方法或属性名称在同一访问范围内使用的变量。还检测在 GVL 中声明的变量 设备 查看或在 POU 池中。然而,为此,GVL POU 视图必须在应用程序中使用。 说明:相同的名称在阅读代码时可能会造成混淆,如果无意中访问了错误的对象,它们可能会导致错误。我们建议您使用
SA0014:实例分配 检测功能块实例的分配。在具有指针或引用变量的实例的情况下,这些赋值具有潜在的风险。 理由:这是一个性能警告。当一个实例分配给另一个实例时,所有元素和子元素都从一个实例复制到另一个实例。指向数据的指针也会被复制,但不会复制它们引用的数据,因此目标实例和源实例在赋值后包含相同的数据。根据实例的大小,这种分配可能会持续很长时间。例如,如果应该将一个实例传递给一个函数进行处理,那么
SA0015:通过 FB_Init 访问全局数据 通过方法检测功能块对全局变量的访问 FB_Init .此变量的值取决于初始化的顺序。 理由:根据 POU 实例的声明位置,如果违反规则,可能会访问未初始化的变量。 重要性:高 例 27 . 例子 VAR_GLOBAL g_xTest1 : BOOL; g_iTest3 : INT; END_VAR METHOD PUBLIC fb_init : B
SA0017:对指针变量的异常赋值 检测对既不是地址的指针的分配( ADR 运算符、指针变量)或常量 0 理由:如果为指针分配的值不是有效地址,则指针的取消引用会导致“访问冲突异常”。 重要性:高 例 29 . 例子 PROGRAM PLC_PRG VAR pInt : POINTER TO INT; dwAddress : DWORD; END_VAR dwAddress := dwAddres
SA0018:异常位访问 检测对有符号变量的位访问。但是,IEC 61131-3 标准只允许对位域进行位访问和位移操作。另请参阅严格的规则 SA0147 和 SA0148 . 另请参阅严格规则 SA0147 和 SA0148 。 理由:有符号数据类型不应用作位字段,反之亦然。 IEC 61131-3 标准不提供这种访问,因此您在编写可移植代码时应遵守此规则。 重要性:中等 提示 标志枚举的例外:当
SA0020:可能将截断的值分配给 REAL 变量 检测对整数变量的操作,其截断值可以分配给 REAL 数据类型变量 理由:当整数计算的结果分配给一个 REAL 或者 LREAL 多变的。应该提醒程序员注意对这种赋值的可能错误解释: lrealvar := dintvar1 * dintvar2 . 因为取值范围 LREAL 大于 DINT ,可以假设计算的结果总是可以表示为 LREAL .但事实
SA0021:传输临时变量的地址 检测临时变量(在堆栈上)到非临时变量的地址分配 理由:函数或方法的局部变量是在堆栈上创建的,它们仅在处理函数或方法时才存在。如果一个指针在处理完方法或函数后指向这种变量,那么你可以使用这个指针访问未定义的内存,或者访问另一个函数中不正确的变量。应不惜一切代价避免这种情况。 重要性:高 例 32 . 例子 FUNCTION TempVarInFUNC : DWORD
SA0022:(可能)未分配的返回值 检测所有包含执行线程但未分配返回值的函数和方法 理由:函数或方法中未分配的返回值表示缺少代码。即使返回值总是有一个默认值,再次显式分配它以避免混淆总是有用的。 重要性:中等 例 33 . 例子 FUNCTION FUN : DINT VAR_INPUT bTest : BOOL; END_VAR IF bTest THEN RETURN; END_IF FUN