【发布时间】:2019-03-29 11:12:46
【问题描述】:
假设我们有两个函数fct1 和fct2:
-
fct1致电fct2, -
fct1将应用程序中的某个对象O1设置为A状态, -
fct2将应用程序中的某个对象O2设置为状态B。
让我们假设以下约束必须始终为真:
- (
01处于A状态并且02处于B状态), - XOR(
01处于not(A)状态并且02处于not(B)状态)。
如果打电话到fct1会发生什么:
- 重新定义:
fct1现在将一些对象01设置为状态not(A), - 重新定义:
fct2现在将某些对象02设置为状态not(B)。
它可以通过将01 设置为状态A 和02 设置为状态not(B) 来“打破”约束吗?
我找到了这个答案: https://stackoverflow.com/a/20477763/9614866
如果递归函数重新定义自身,则在同一调用中仍要进行的递归调用可能会继续转到同一个主体。 [...] 更一般地说,Common Lisp 允许编译器在同一文件中的函数之间生成有效的调用。因此,您通常必须将运行代码的替换视为模块级别而不是单个功能级别。如果函数 A 和 B 在同一个模块中,并且 A 调用 B,那么如果您只是替换 B 而不替换 A,A可能继续调用旧 B(因为 B 内联到 A,或者因为A 不通过符号,而是为 B) 使用更直接的地址。你可以声明函数 notinline 来抑制这个。
我的问题是:
- 会不会出现这种现象(即
01设置为A状态,02设置为not(B)状态)?它有名字吗?
如果“是”:
- 它是否依赖于实现?
- 有没有办法强制正确的行为,例如通过内联函数?
- 我可以使用哪些工具来测试这些功能是否以正确的方式工作?测试似乎很痛苦:我不知道如何在不更改基本源代码的情况下测试重新定义。
- 如何检测可能出现此问题的代码部分?
【问题讨论】:
-
除非对象可以同时处于状态
A和not(A),否则您的条件是矛盾的(不可能同时为真)。 -
如果您愿意,我可以编辑问题。 :)
标签: common-lisp slime