Adriaan van Os wrote:
There are other holes, such as dangling pointers and using unintialized variables, which GPC cannot detect at all yet. It might do in the future, but implementing them will be very hard, so don't hold your breath.
I have always presumed that -Wuninitialized (combined with -On, where n
=1) does warn about uninitialized variables. The following simple test
seems to confirm that, but only for local variables, not for global variables (which maybe are automatically initialized to 0 ?? (a dangerous presumption by the way)).
These are static (compile-time) checks, i.e., when a variable *might* be used unintialized. Checking when a variable actually is used uninitialized can only be done at runtime. Of course, catching too much shouldn't hurt (except for some spurious warnings, that you probably have seen yourself, which can be worked-around after careful verification).
However, the static checks only work for entire local variables. In particular they don't work for:
- global variables -- as you say they are automatically initialized to 0, but that's only a C heritage of the backend, and not guaranteed in Pascal, so actually there should be a warning.
- heap-allocated variables -- since not even the number of allocations is generally known at compile-time, they can't usually be statically checked
- variant record fields -- according to standard Pascal, all fields become undefined when changing the variant (by assignment to the selector if present, or if not present, by using some field of another variant). That's also generally only known at runtime.
- record/array fields -- currently GPC warns only for the whole structure. Though it would be possible (at least in principle) to extend it to record fields, and components of arrays with compile-time known bounds, it's not for arrays of dynamic size.
- for-loop counters -- according to Pascal, they become undefined after (regular) termination of the loop. GPC currently doesn't do it, and it seems hard to do with the backend.
Actually, the warning it not even always conservative. For var-parameters, we assume they can modify the variable (otherwise, there would be many spurious warnings). So the following program gives no warning.
program Uninitialized2;
procedure p (var a: Integer); begin WriteLn (a) end;
procedure q; var i: Integer;
begin p (i); WriteLn (i) end;
begin q end.
Static analysis of runtime-dependent behaviour (as basically all such cases) is usually very difficult to impossible (cf. halting problem). Runtime analysis seems to require an implicit flag for each variable or field (some type have unused bit-patterns that could be used instead, but not all do), which would have to be set and checked on each access. The considerations WRT performance and externals routines (see my parallel mail about memory checking) apply here as well.
Frank