Version 9 of if 0 {

Updated 2003-03-18 14:13:07

SB: Somebody care to explain why this search give so many hits?

http://mini.net/tcl/2?if+0+{*

NEM - It's used a lot in pages which are mostly code. By surrounding the non-code explanation parts in

if 0 {

This is some explanation

}

Then the whole page can be copied and pasted into a tclsh/wish/tkcon without the explanation bits causing an error. It's just a way of doing block commenting.

escargo 16 Mar 2003 - Isn't part of the point of this construct that no bytecodes get generated for any of the text included inside the curly braces? This removes any runtime penalty for including useful info (however structured) inside those braces?

NEM Yes, that's true. I imagine normal Tcl comments produce no bytecode too, though. The runtime efficiency of comments is generally not something to worry about unless you need serious performance, in which case you should probably be thinking about moving to C or some other language for that task.

escargo I thought ordinary comments (that is with the # command) got parsed and substituted, etc. Does that step get skipped for the the if 0... construct?

NEM I'm out of my depth now. I'm really not sure what happens with comments, especially when the byte-compiler is involved. I don't think comments get substituted, as this example demonstrates:

 % # [set a 1]
 % set a
 can't read "a": no such variable

From this, I would assume that comments produce no bytecode, but I'll defer to someone who actually knows. Another quick test is the following:

 % proc test1 {args} {}
 % proc test2 {args} {
 # This is a long set of comments with [substitions]
 # of various forms: $args. {} Blah blah blah
 }
 % proc test3 {args} {
 if 0 {
 This is a long set of comments with [substitutions]
 of various forms: $args. {} Blah blah blah
 }
 }
 % time test1 100000
 1 microseconds per iteration
 % time test2 100000
 27 microseconds per iteration
 % time test3 100000
 28 microseconds per iteration
 % info patchlevel
 8.4.2

So, from this it seems that a proc with comments in is not optimized away like the empty proc is. Also, there appears to be little or no difference between a standard comment and an if 0 block, at least for very small tests. Neither proc throws an error (from the bad command name substitutions), so I think neither performs substitutions. I also did a bigger test by using [string repeat] to build up a long comment and then defining the same procs as above, with the longer comment (14000 characters), and the times were roughly equivalent (although the if 0 construct was a couple of microseconds longer each time).


MS answers:

  • a proc where (a) the argument list is {args} and (b) the body is all spaces is compiled to just "substitute the arguments (in case there are any side-effects), then push an empty result". Procs where the body consists of comments are not optimised this way, in order to reduce the compile-time overhead. Remember that this optimisation was introduced as a way to allow fast assertions in Tcl.
  • all other procs compile "subst and push the arguments, call the proc"
  • standard comments compile to strictly nothing
  • "if 0 { ... }" compiles to "push an empty result"

BTW, your test here is hitting bug #458361 [L1 ], so that the proc body is parsed and compiled at each call. In order to avoid that and do a fair test, do call instead

   time {test2 } 100000

Witness the results:

 % time test1 100000
 1 microseconds per iteration
 %  time test2 100000
 25 microseconds per iteration
 % time test3 100000
 21 microseconds per iteration
 % time {test2 } 100000
 4 microseconds per iteration
 % time {test3 } 100000
 4 microseconds per iteration

DKF - The if 0 {...} construct does result in bytecodes not being generated for the body, though this doesn't usually make that much difference since the best that you could do would be to skip about two bytecodes...


[ Category Internals ]