【发布时间】:2016-12-24 01:27:03
【问题描述】:
我对TCL执行的理解是,如果定义了一个命令的编译函数,那么在调用它的执行函数之前,它会在执行该命令时首先被调用。
以命令 append 为例,在 tclBasic.c 中定义如下:
static CONST CmdInfo builtInCmds[] = {
{"append", (Tcl_CmdProc *) NULL, Tcl_AppendObjCmd,
TclCompileAppendCmd, 1},
这是我的测试脚本:
$ cat t.tcl
set l [list 1 2 3]
append l 4
我在 TclCompileAppendCmd 和 Tcl_AppendObjCmd 这两个函数中添加了 gdb 断点。我的期望是在 Tcl_AppendObjCmd 之前命中 TclCompileAppendCmd。
Gdb 的目标是 tclsh8.4,参数是 t.tcl。
我看到的很有趣:
- TclCompileAppendCmd 确实首先被命中,但它不是来自 t.tcl, 而是来自 init.tcl。
- TclCompileAppendCmd 被多次命中,它们都来自 init.tcl。
- t.tcl 第一次执行,是 Tcl_AppendObjCmd 被命中,而不是 TclCompileAppendCmd。
我无法理解它:
为什么为 init.tcl 调用编译函数而不为 t.tcl 调用编译函数?
每个脚本都应该独立编译,即在 init.tcl 处附加编译命令的对象不会被以后的脚本重用,不是吗?
[更新] 感谢Brad 的提示,在我将脚本移动到 proc 后,我可以看到 TclCompileAppendCmd 被命中。
【问题讨论】:
-
尝试将您的测试放入 proc 中。 Q2 有某种错误的假设。
append命令已编译。 -
这是 Tcl 字节码编译器的怪癖之一。一般来说,一旦脚本开始变长,创建一个主过程并将所有内容放入其中以便编译。
-
EDA 工具中的非常大的脚本除外。那些遇到了一些可怕的内存限制......
标签: tcl