Avoiding Crying Wolf With Warnings



Janus/Ada has always been a "noisy" compiler. It prints strings of progress symbols while it works, information about memory usage, program size, and the like when it is done, and even has a friendly sign-off message. This policy spills over into warnings, where the compiler will warn you about almost anything that might matter to you. Janus/Ada is noisy in part because of our experience with other compilers when we were starting out. Computers were a lot slower in 1981 (the 4 MHZ Z-80 running CP/M that was one of the original targets was more than 2500 times slower than the Windows box on which I write this); compilation times for each file were measured in minutes rather than seconds. Early compilers that followed a minimalist philosophy (like the early Unix compilers) could leave a programmer staring at a blinking cursor for 5 minutes or more before any result occurred. Since early computers (not to mention software) were nowhere near as reliable as today's machines, that made it impossible to tell if the compiler was even working. At times, I'd wait 30 minutes only to find out that something had gone wrong and the compile hadn't finished at all. Therefore, when we started building our own compiler, we wanted it to print something at least every second or so in order that we could tell it was in fact working rather than having died because of a memory fault. The same philosophy extended to compiler error reporting. We'd used some compilers with very minimalist error handling, the Unix C compiler being the worst. It seemed that it had only two error messages: "lvalue expected" at compile time and "bus error, core dumped" at runtime. From those you had to figure out what the problem was and how to fix it. We'd also used the UW Pascal compiler, which had been designed for introductory programmers to use. It had very detailed error messages both at compile-time and runtime (it even dumped all of the local variables in the error walkbacks). It was clear which of these we wanted our compiler to be like! Thus we've included warnings about a wide variety of things, from cases where exceptions are always going to be raised to ranges that are null (contain no values). Some of them usually need action, some never need action, and others are in between. This wide spread of warnings has periodically confused Janus/Ada users, causing them to think they need to change the type of a component, or causing them to suppress all warnings, thus missing messages about likely bugs in their code. Thus, future versions of Janus/Ada (starting with the forthcoming Preview) now have both Informational Messages and Warnings. The basic idea is that a warning describes a condition that probably should be eliminated, while an informational message describes performance or stylistic conditions that do not necessarily require action. Informational messages can be suppressed separately with their own option (/YI) and all are suppressed if all warnings are suppressed with the /W option. (If only some of the warnings are suppressed, informational messages are not suppressed.) We've also added a Treat Warnings as Errors option (/YW) which allows a project to ensure that no warnings remain in a fielded system (as no code will be generated if any errors exist). This split leaves some old warnings in a grey area. For instance, consider Some or all of the code on this line is unreachable. This can indicate a problem if the indicated code is an important part of the program. But it is just as likely to indicate some code that is unused by Ada conditional compilation (that is, an if statement controlled by a Boolean constant), and in a few cases might indicate some compiler-generated data structure is unused (such as the table used to implement Subtype'Image). As such, we eventually decided to treat this as an informational message. Similarly, new messages have to be placed in one category or the other, and that poses the same problems. Consider, for instance, the new message Ada 2007 feature treated as implementation-defined. You'll see this if you compile in Ada 95 mode (/Y5) and you with package Ada.Directories, for instance. There's no real problem with doing so; the package will work as expected. That argues for it to be an informational message. However, the main use of the /Y5 flag is to ensure that code is portable to other compilers, and one cannot expect an Ada 95 compiler to have package Ada.Directories. That suggests that the use of Ada.Directories ought to be replaced by something else, and that's what warnings are for. Thus we settled on making this a warning with a large level (so it is easy to suppress, in this case with the /W8 option). [On the third hand, if you're compiling for maximum portability, you're also using /IX (to set No_Implementation_Extensions) along with /Y5, and that will make uses of Ada.Directories an error with a different message. So what to do is never completely clear!] Having informational messages also allows Janus/Ada to report additional issues that would be confusing to report as warnings. For instance, a new informational message in Janus/Ada is Feature is obsolescent, consider replacing. Obsolescent features can continue to be used as they're still a required part of the Ada Standard, so this is more advice than a demand. As such, it is inappropriate as a warning, but it is fine as an informational message. We hope these changes will reduce or even eliminate the need to suppress warnings in normal usage. That way, one won't have to have a testing failure to find out about potential bugs identified by the compiler. On the other hand, suppressing informational messages may be valuable if there are too many of them; doing so will not eliminate anything really critical. Undoubtedly these changes won't work for everyone. If you have thoughts on this topic, please sent them to me at randy@rrsoftware.com.