在CODESYS 中,一般允许对不同元素使用相同的标识符。例如,POU 和变量的名称可以相同。但是,为了避免混淆,您应该避免这种做法。
反面例子在下面的代码片段中,本地函数块实例的名称与函数相同:
示例
FUNCTION YYY : INT ; END_FUNCTION FUNCTION_BLOCK XXX ; END_FUNCTION_BLOCK PROGRAM PLC_PRG VAR YYY : XXX; END_VAR YYY(); END_PROGRAM
在这种情况下,不清楚程序中调用的是实例还是函数。
为确保名称始终唯一,应遵循命名约定,如变量的特定前缀。关于分配标识符的规则,请参阅帮助中的 "标识符 "一章。
可使用CODESYS 的静态代码分析功能自动检查命名约定。静态代码分析也可以检测到YYY
名称的重复使用,并将其作为错误报告。
在枚举和全局变量列表中统一使用属性qualified_only
,以及使用限定库,也可以避免出现模棱两可的情况。
为确保在调用“POU”视图中的 POU 时,不会调用“Devices”视图中的同名 POU,应在调用 POU 名称时,在操作符__POOL
前加上操作符(例如svar_pou := __POOL.POU();
)。
映像 :如果不同元素使用了相同的标识符,编译器不会报告任何错误或警告。相反,编译器会按照特定顺序在代码中搜索标识符的声明。如果找到一个声明,编译器就不会在其他地方搜索任何其他声明。如果确实存在其他声明,编译器会对它们进行 "映像处理"。下文将介绍映像规则(即编译器在搜索标识符声明时使用的搜索顺序)。模糊访问和合格访问 "部分提供了防止模糊访问和绕过映像规则的方法。
应用程序中的搜索顺序
当编译器在程序代码中遇到单个标识符时,会按以下顺序查找相应的声明:
1.方法的局部变量
2.功能块、程序或函数中的局部变量,以及任何基础功能块中的局部变量
3.POU 的本地方法
4.应用程序中的全局变量,如果在声明全局变量的变量列表中没有设置qualified_only
属性
5.父应用程序中的全局变量,如果在声明全局变量的变量列表中未设置qualified_only
属性
6.当库或变量列表都不需要限定访问权限时,引用库中的全局变量
7.来自应用程序的 POU 或类型名称(即全局变量列表、功能块等的名称)
8.来自父应用程序的 POU 或类型名称
9.POU 或来自库的类型名称
10.本地引用的图书馆和图书馆发布的图书馆的命名空间
11.“POUs” 视图中的全局变量,除非在声明这些变量的变量列表中设置了qualified_only
属性
12.“POUs” 视图中的 POU 或类型名称(即全局变量列表、功能块等的名称)。
在“POUs” 视图的库管理器中插入的库,会以适当的占位符分辨率镜像到项目中所有应用程序的库管理器中。然后,这些库与应用程序中的库组成一个公共命名空间。因此,应用程序中的库不会对库中的库产生映像。
库中的搜索顺序
当编译器在库代码中遇到单个标识符时,会按以下顺序查找相应的声明:
1.方法的局部变量
2.功能块、程序或函数中的局部变量,以及任何基础功能块中的局部变量
3.POU 的本地方法
4.本地库中的全局变量,如果在声明全局变量的变量列表中未设置qualified_only
属性
5.当库或变量列表都不需要限定访问权限时,引用库中的全局变量
6.本地库中的 POU 或类型名称(即全局变量列表、功能块等的名称)
7.POU 或引用库中的类型名称
8.本地参考图书馆和由本地参考图书馆出版的图书馆的命名空间
模糊准入和合格准入
尽管有这些搜索命令,但仍可能发生模糊访问。例如,当一个同名变量存在于两个不需要限定访问权限的全局变量列表中时,就会出现这种情况。编译器会将这种情况报告为错误(例如:ambiguous use of the name XXX
)。
通过限定访问,例如通过全局变量列表的名称进行访问(例如:GVL.XXX
),可以使这种含糊不清的用法变得独一无二。
合格的访问也总是可以用来规避映像规则。
-
全局变量列表的名称可用于唯一访问列表中的变量。
-
库名可用于唯一访问库中的元素。
-
THIS
指针用于唯一访问功能块中的变量,即使在功能块的方法中存在同名的局部变量。
要随时查找标识符的声明位置,请使用“Edit Browse Go to Definition” 命令。如果编译器产生了明显晦涩难懂的错误信息,这一点尤其有用。
在实例路径中搜索
上述搜索命令不适用于在实例路径中作为组件存在的标识符,也不适用于在调用中作为输入的标识符。
对于以下类型的访问yy.component
,它取决于yy
所描述的实体,在该实体中搜索component
的声明。
如果yy
表示具有结构化数据类型的变量(即类型为STRUCT
或UNION
),则component
将按以下顺序进行搜索:
-
功能块的局部变量
-
基础功能块的局部变量
-
功能块的方法
-
基础功能块的方法
如果yy
表示全局变量列表或程序,则component
只在该列表中搜索。
如果yy
表示一个库的命名空间,则component
在该库中的搜索顺序与上文 "库中搜索顺序 "一节所述完全相同。
只有在第二种情况下,编译器才会决定是否允许访问找到的元素(也就是说,变量是否只能本地访问,或者方法是否是私有的)。如果不允许访问,则会出错。