我将总结我现在的发现(在 Simon Wright 和 G_Zeus 的帮助下)。如果我错了,请纠正我:
根据标准,L = null
, R = null
, L = R
也L.Next = R.Next
每个都应该明确调用用户定义的运算符=。universal_access
运算符 = 绝对不能在这里起作用。
Reason:
操作数L
, R
, L.Next
and R.Next
违反了前提条件ARM 4.5.2(9.1-9.4) http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-4-5-2.html#p9.1用于口译=
在这些表达式中,运算符 = 的意思是universal_access
type:
前提条件是两个操作数都不是访问对象类型(access Cell
) 其指定类型为Cell
(check), Cell
有一个用户定义的原始相等运算符(check)这样
- 它的结果类型是
Boolean
(check);
- 它立即在同一声明列表中声明
Cell
(check); and
- 其操作数中至少有一个是指定类型的访问参数
Cell
(两个操作数都是,check).
运算符 = 的优先规则universal_access
输入ARM 8.6(29.1) http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-8-6.html#p29.1不适用于此处,因为它需要“两种可接受的解释”。但由于4.5.2,操作符=universal_access
type 不是可接受的解释。
所以别无选择:在所有情况下(甚至L = null
) 它必须是用户定义的运算符=。
@Simon Wright:所以“无界递归”实际上是正确的编译器行为。
@G_Zeus:发出歧义错误l = r
是不正确的编译器行为,编译器应该选择Access_Equal."="
.
该示例应正确读取:
...
if Standard."="(L, null) or Standard."="(R, null) then -- universal =
return Standard."="(L, R); -- universal =
elsif L.Value = R.Value then
return L.Next = R.Next; -- recurses OK
...
Cheers.