【发布时间】:2016-05-10 20:06:54
【问题描述】:
一位朋友让我查看this page,并注意到其中一位论坛用户的签名中有一段奇怪的代码。
代码是单行的,如下所示:
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
已移除滚动:
On Local Error Resume Next: If Not Empty is nothing then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True )))): Stop: On Local Error GoTo 0
非常令人兴奋的是,如果您只是将它按原样粘贴(然后不要再触摸它!)到有效的过程级别,那么该代码会编译(我没有尝试运行它,但这无关紧要)范围。
一些观察:
- 如果将指令分隔符/冒号替换为新行,则不再编译
-
On Local Error可以简化为On Error - 乍一看,嵌套转换并没有什么特别的意义,但事实证明,用简单的
Debug.Assert True替换这一系列转换和比较可以使代码始终编译,所以 something in编译器搞砸了。 - 如果粘贴代码,则编译;如果在 VBE 验证该行之后以任何方式对其进行了修改(甚至只是删除了
Local),它会停止编译,并且似乎没有任何东西可以让 VBA 再理解它,除非该行被删除并重新粘贴。 - 最新的rubberduck 语法/解析器非常接近实际的 VBA 规范 it parses and resolves just fine(这真的让我大吃一惊)
- 如果已知该行无法编译,然后剪切/重新粘贴,它不会编译...但从 VBE 外部再次重新粘贴,它会突然编译。
问题是,这段代码是如何根据 VB 语言规范编译的?它是 VB[6|A|E] 实现中的错误吗?换句话说,为什么/如何工作?
我认为它与指令分隔符 (:) 和 inline-if 语法有关 - 鉴于没有 End If 语句,事情 是 单行而不是块。
但是,是什么让特定代码成为薛定谔的代码?是什么让它既合法又非法?
如果代码被使用正式语法定义 (ANTLR) 生成的解析器正确解析,那么它一定是合法构造吗?那为什么当你只是回到那一行并按 ENTER 时它就不再合法了?
【问题讨论】:
-
在那只讨厌的猫消失之前,我正要纠正给薛定谔,再次
-
是否将嵌套转换简化为 True,让代码保持相同的 2 个状态?
-
@ThunderFrame it... 没有(当它显示
Debug.Assert True时,您可以再次编辑它,它保持可编译状态)。似乎嵌套转换确实很重要。 -
有趣的是,如果您手动输入它,它也不会编译。是否可以在文本中隐藏控制代码?这在很久以前是可能的,但我认为你不能再这样做了。
-
无法在 VB6 上重现。
标签: rubberduck vba vb6 specifications vbe