Mat*_*don 12 vb6 vba specifications vbe
一位朋友让我看看这个页面,并注意到一个论坛用户的签名中有一段奇怪的代码.
代码是一个单行,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
滚动删除:
关于本地错误恢复下一个:如果不为空则没有,然后做空:ReDim i(真假)作为货币:循环:其他Debug.Assert CCur(CLng(CInt(假冒错误真Xor假Eqv真))) ):停止:On Local Error GoTo 0
相当令人兴奋的是,代码编译(我没有尝试运行它,但这是无关紧要的)如果你只是按原样粘贴它(然后再不要再触摸它!)到一个有效的程序级范围.
一些观察:
On Local Error
可以简化为 On Error
Debug.Assert True
会使代码一致地编译,因此其中的某些东西会弄乱编译器.Local
在VBE验证了行之后以任何方式修改它(甚至只是删除),它就会停止编译,似乎没有任何东西让VBA理解它,除非该行被删除并重新粘贴.问题是,这段代码如何根据VB语言规范进行编译?这是VB [6 | A | E]实现中的错误吗?换句话说,为什么/如何运作?
我认为它是与指令分离器(:
)和直列如果语法-考虑有没有End If
说法,事情是单线,而不是块.
但是,那些特定代码是什么使Schrödinger的代码?什么使它既合法又非法?
如果使用正式语法定义(ANTLR)生成的解析器正确解析代码,那么它必须是合法的构造吗?那么为什么当你回到那条线并点击ENTER时它就不再合法了?
Thu*_*ame 13
有了这么长的代码行,很难发现编译错误的位置,但是有一个微妙的区别,似乎是VBE对该行应用了一个自动更正,或者更有可能在解析之后.
在您将光标移动到另一行之前,该行显示为这样.注意以及关键字语句之间的Loop
Else
粗体冒号:
在本地错误恢复下一个:如果不为空则没有,然后
Loop: Else
做空:ReDim i(真假)作为货币:Debug.Assert CCur(CLng(CInt(假冒错误真Xor假Eqv真)))):停止:On Local Error GoTo 0
请注意,VBE已自动删除冒号.似乎VBE解析器识别该语句,然后"优化""冗余"冒号.
在本地错误恢复下一个:如果不为空则没有,然后
Loop Else
做空:ReDim i(真假)作为货币:Debug.Assert CCur(CLng(CInt(假冒错误真Xor假Eqv真)))):停止:On Local Error GoTo 0
如果将冒号添加回处于无效语法状态的行,则自动更正会再次启动,但您的行将返回有效但易碎的代码.
因此,似乎VBE解析行,识别优化(冗余冒号),然后应用修复,但VBE没有意识到优化行有语法问题.
但为什么这条线最终会变得脆弱?该行中有许多令人分心和不相关的关键字,所以让我们大幅减少它:
如果我们最小化线路的复杂性,为了隔离问题,我们可以将线路简化为:
If True Then Do While True: Beep: Loop: Else
再次,VBE自动修正到脆弱的线路:
If True Then Do While True: Beep: Loop Else
但我们可以更进一步,将线路减少到不合逻辑的短线:
If True Then Do: Loop: Else
和VBE ,再次,尽职尽责地删除冒号以产生这一行:( 不要执行此行或您将挂起)
If True Then Do: Loop Else
重复该行,但换掉
Do While Loop
旧While Wend
语法:
If True Then While True: Beep: Wend: Else
再次,VBE优化掉冒号,给予:
If True Then While True: Beep: Wend Else
但现在该行不再脆弱了!
因此,While..Wend是较旧的构造,而Do..Loop构造是更新的(并且更灵活),但似乎VBE解析器(和语法优化器)与Do..Loop构造斗争.
关键点:不要Do..Loop
在If
包含Else
语句的单行语句中使用.