在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属性的一致使用以及对合格库的使用也可以防止产生歧义。
阴影:如果将相同的标识符用于不同的元素,则编译器不会报告任何错误或警告。而是,编译器按特定顺序在代码中搜索标识符的声明。如果找到了声明,则编译器不会在其他位置搜索任何其他声明。如果确实存在其他声明,则它们对于编译器是“阴影”的。以下部分描述了屏蔽规则(即,编译器在搜索标识符声明时使用的搜索顺序)。“歧义访问和合格访问”部分提供了防止歧义访问和绕过影子规则的方法。
应用程序中的搜索顺序
当编译器在应用程序代码中遇到单个标识符时,它将按以下顺序搜索相应的声明:
1.方法的局部变量
2.功能块,程序或函数以及任何基本功能块中的局部变量
3.POU的本地方法
4.如果未在声明全局变量的变量列表中设置qualified_only属性,则应用程序中的全局变量
5.如果未在声明全局变量的变量列表中设置qualified_only属性,则父应用程序中的全局变量
6.当库和变量列表均不需要合格访问时,引用的库中的全局变量
7.应用程序中的POU或类型名称(即,全局变量列表,功能块等的名称)
8.来自父应用程序的POU或类型名称
9.来自库的POU或类型名称
10.本地引用的库的名称空间以及由库发布的库
11.在POUs视图中的全局变量,除非在声明它们的变量列表中设置了qualified_only属性
12.POU或POUs视图中的类型名称(即,全局变量列表,功能块等的名称)
|
插入到POU视图的“库管理器”中的库将以适当的占位符分辨率在项目中所有应用程序的“库管理器”中进行镜像。然后,这些库与应用程序中的库形成公共命名空间。因此,应用程序中的库不会在池中隐藏库。 |
库中的搜索顺序
当编译器在库代码中遇到单个标识符时,它将按以下顺序搜索相应的声明:
1.方法的局部变量
2.功能块,程序或函数以及任何基本功能块中的局部变量
3.POU的本地方法
4.如果未在声明全局变量的变量列表中设置qualified_only属性,则本地库中的全局变量
5.当库和变量列表均不需要合格访问时,引用的库中的全局变量
6.来自本地库的POU或类型名称(即全局变量列表,功能块等的名称)
7.引用库中的POU或类型名称
8.本地引用库的名称空间以及由本地引用库发布的库
歧义访问和合格访问
尽管有这些搜索顺序,但是仍然可能出现歧义访问。例如,在两个不需要合格访问的全局变量列表中存在具有相同名称的变量时,就是这种情况。编译器将这种情况报告为错误(例如:ambiguous use of the name XXX).
这种模棱两可的用法可以通过限定访问来实现,例如通过全局变量列表的名称来访问(例如: GVL.XXX)。
合格的访问也可以总是用来避免阴影规则。
要随时查找标识符的声明位置,请使用命令。如果编译器产生明显模糊的错误消息,这将特别有用。
在实例路径中搜索
上述搜索顺序不适用于在实例路径中作为组件存在的标识符或在调用中用作输入的标识符。
对于以下类型yy.component的访问,它取决于yy描述的在其中搜索component声明的实体。
如果yy表示结构化数据类型的变量(即STRUCT或UNION类型),则按以下顺序搜索component:
功能块的局部变量
基本功能块的局部变量
功能块的方法
基本功能块的方法
如果yy表示全局变量列表或程序,则仅在此列表中搜索component。
如果yy表示库的名称空间,则完全按照上面“库中的搜索顺序”部分中的描述在该库中搜索component。
仅在第二种情况下,编译器才决定是否授予对找到的元素的访问权限(即,变量是否只能在本地访问,还是方法是私有的)。如果不允许访问,则会发出错误。