Frank H:
As I said, GPC doesn't check for using undefined values at all. (Currently, and this isn't going to change soon, as this is not exactly trivial to implement in general ...)
I am with Frank on this. Many years ago, before Pascal existed, I used the Watfor Fortran compiler. This compiler always checked for uninitialized variables. The check was made by initializing all variables to the value 666 according to length (e.g., Boolean variables were set to x'66', fullword integers to x'66666666' and so forth). Every time a value was fetched it was checked for these values. This nearly doubled running times.
A bigger problem was that the value 666 sometimes came up naturally in the course of computation. That would abort your run. It took a great deal of tricky programming to prevent this from happening.
The alternative method of checking for uninitialized variables is to have a separate set of flags, one for every variable and component of every array and data structure. This not only costs heavily in execution time, it also costs in storage.
Switching back and forth from checking On to checking Off might be more complex than simply turning on and off the option. There may be consequences due to having your variables change location.
All told, I don't think the check for uninitialized variables is worth the effort.
Frank Rubin
Contestcen@aol.com wrote:
As I said, GPC doesn't check for using undefined values at all. (Currently, and this isn't going to change soon, as this is not exactly trivial to implement in general ...)
I am with Frank on this. Many years ago, before Pascal existed, I used the Watfor Fortran compiler. This compiler always checked for uninitialized variables. The check was made by initializing all variables to the value 666 according to length (e.g., Boolean variables were set to x'66', fullword integers to x'66666666' and so forth). Every time a value was fetched it was checked for these values. This nearly doubled running times.
A bigger problem was that the value 666 sometimes came up naturally in the course of computation. That would abort your run. It took a great deal of tricky programming to prevent this from happening.
Exactly. These are the two main problems. For the first one, of course, it should be up to the programmer whether to take the penalty, i.e. it should be switchable off.
For the second one, Booleans are actually among the more harmless cases. Chars can use up all possible values (depending on the charset -- Unicode might have some free spaces). Integers according to ISO Pascal have one unused value, but other dialects use this value, so we can't really use it safely. And for reals, we have various formats to deal with ...
The alternative method of checking for uninitialized variables is to have a separate set of flags, one for every variable and component of every array and data structure. This not only costs heavily in execution time, it also costs in storage.
Indeed. If I was going to implement it, I'd probably do this, to avoid the troubles described above, but the result would not be very efficient at all. That doesn't mean useless -- for some (actually, I think many, today) cases, efficiency is unimportant, and this penalty is well worth the additional checks.
Switching back and forth from checking On to checking Off might be more complex than simply turning on and off the option. There may be consequences due to having your variables change location.
Yes, but if the program is perfectly checked (which involves more checks such as range-checking that we have, and others we don't have yet), that shouldn't matter anymore.
Perhaps a bigger problem would be external calls (C libraries etc.), which wouldn't respect or update these flags. ATM, I don't see anything better than hand-written wrappers. Automatical generation probably isn't possible, as they'd have to know about the semantics of the external routines. Much work ...
All told, I don't think the check for uninitialized variables is worth the effort.
I think it would be for some cases. But that's only theoretical to me now, as I won't have the time to really think about implementing it in the foreseeable future ...
A completely different solution not discussed here yet would be using the memory-protection capabilities of modern OS's. That's similar to what efence does for heap allocations, but also for global and local variables. And in addition to disallocating freed variables (on the OS level), undefined variables could be left unreadable, but writable and turned readable when they're written (*if* the OS supports this -- I think IA32 and probably other hardware does at least).
The advantage would be that the implementation would be comparably simple and language-independent (no problems with external libraries, provided they were also compiled this way). The disadvantages would be that it's rather OS dependent, and very wasteful on memory. E.g., IA32 supports memory protection only on a page (4KB) basis, and allocating 4KB for each variable, let alone array/record fields, would be tolerable only for some kinds of applications ...
Frank