Version 15 of tclchecker

Updated 2014-01-11 17:15:27 by RLE

Summary

TclChecker is a fork of procheck, the static analysis tool that is included with Tcl Dev Kit

Documentation

official reference ,version 5.3

Description

TclChecker covers the extended commands of Tcl 8.4 and 8.5, fixes bugs in the checking for other versions, adds checks for new possible errors, and was also integrated with tcldebugger and the Komodo IDE.

Additional .pcx files for Tcl extensions

LV: So, has anyone created the necessary .pcx files to allow tclchecker to check the more common tcl extensions? TDK comes with some documentation on creating these files. However, they are relatively complex. It would be useful to try and take the info from the doc and try to write a usable .pcx file, just to work out the kinks of how things work. It seems pretty complex.

AK: I have .pcx files for some of the packages in Tcllib. I will commit them (incrementally) to Tcllib. They will require version 4.1 of Tcl Dev Kit.

 Musings (a kind of review)

Peter Lewerin: I tried TclChecker on some of my longer programs today (2014-01-11). I'm not quite sure how I feel about it. TC didn't find very much to complain about, which I suppose could be because I'm just that good -- OTOH, it could mean that TC fails to detect anything beyond the most obvious blunders. So, what did it find?

  1. I sometimes omit the default clause in a switch command. Yikes.
  2. I sometimes omit -- before the string argument in a switch command. Oops. (TC did not complain about me omitting the -- in a regexp command, however, even when I used a variable dereference for the exp value.)
  3. I tend to omit the optional level argument to upvar.
  4. I occasionally use constructs like set $varName foo or variable $varName foo, for instance when initializing a bunch of variables in one action, or append $varName foo if I need to select which variable to append to. TC doesn't like any of these, but is satisfied when I change $varName to [set varName] (which does make sense, since that's a lot less likely to be a mistake). It does recognize and accept the idiom upvar 1 $varName myVar.
  5. A lot of undefined variables that actually were defined: TC got confused in a couple of cases when variables were being set using regexp (there was some indirection involved) or using dict with. (TC is a static analysis tool after all, so I don't really blame it for not figuring it out here.)
  6. I tend to omit the braces around the condition in an if command if all of the condition is a variable dereference, a command invocation, or a boolean literal such as no or 0 (mostly used when excluding sections of code "Bauersachs braces"-style). TC gets concerned about "avoid[ing] double substitution and/or performance degradation".

(List roughly sorted in order of what I feel is justified to complain about.)

1 and 2: yes, those are valid points, I fixed those cases immediately and resolved to keep that in mind (even more than I already did) in the future (I was taught not to do #1 in the early 1980s, and have taught students of my own not to do it: I don't know why I still miss this sometimes).

3: Um, OK, maybe that's valid, even though I can't see myself passing in a variable name starting with a digit or a hash sign. 4: What's the problem, really? (Sure, sometimes it is a bug-causing mistake, and a serious one at that, but it wasn't in any of these cases.) I did make the change to [set varName] while negotiating with TC, but I'm not sure I'll change my ways in the future.

5: This is mainly TC's problem, not mine. I mean, if a variable really is undefined at the point of use, I will notice it not by running a checker, but by the program, you know, crashing. Unfortunately, short of inserting an excluding pragma or a set command to pre-define the variable there doesn't seem to be a way to arrange the source to avoid this kind of false positive.

6. Yes, that might be causing bugs, but it's not very likely, is it? At least, I doubt that the string "no" will end up giving me double substution or performance problems. And if your conditions evaluate to something other than a boolean value in the first place, maybe Tcl isn't for you. (Alternatively, you're writing code that relies on that double substitution, in which case you don't want the braces anyway.)

RLE (2014-01-11): This is a potential issue in several ways. One, if at some much later point in time the variable contains something much more dangerous than "no", you've got a "surprise" bug that can be hard to track down. Second it interferes with bytecode compiling [L1 ] [L2 ]. Generally it is better to get into the habit of always bracing the expression to an if, then you are less likely to forget the braces when you do actually need them.

Also, even though I specified version 8.6, TC didn't recognize the lmap command. Neither did it know about cmdline. It did check oo for some reason (I wasn't using OOP). Namespace ensembles seem to be a mystery to it.

I think I will test TC once more while actually creating a program (as opposed to trying it on working, more-or-less error-free programs). Maybe it will prove more useful in that situation.

In summary: if I were the manager of a team of programmers I'd insist on everyone using TC before checking in code because it would be good practice (a work environment is no place for idiosyncrasies or code that is even remotely dubious). For myself as a hobby programmer, I'm good if the program runs correctly (and I do test them at least informally, out of habit). While I suppose TC can sometimes be really helpful, it wasn't at this time: it mostly came dangerously close to just being a bother. I don't think I'm going to spend the money to get the license for it.