Recently, I encountered a real gotcha while updating a visual design tool. The update included support for a new compiler vendor who was, in fact, becoming the new default compiler. So I updated the tool, loaded a project that worked five minutes earlier, rebuilt the project with no errors and no warnings, and then programmed the part. I applied power, and nothing happened! Not one line of code had changed, and no errors or warnings were generated. What was the problem?
I immediately pulled out my trusty debugger and found that the state of a one-shot timer used at startup had initially been triggered when power was applied. But under the new compiler, the timer state is un-triggered when power is applied. Both compilers claim ANSI compliance, and I have used both compilers without a problem for years. So where was the problem? A closer inspection of the situation provided some real insight into the failure. Intent on finding whose product was responsible, I took a look at the bigger picture.
ANSI C compilers are written to exact standards where ANSI definitions are concerned. This means that both compilers initialize variables to a zero value according to ANSI standards. But one of the compilers also allowed non-ANSI standard code to be initialized while the other didn’t. A few days earlier, an associate and I had a discussion about these same compilers, one of which would allow variables outside the scope of any file to be initialized, while the other compiler would ignore initializing variables that did not adhere to ANSI scope rules.
To complicate matters, the tool being used generated all of the project code. As the developer, I had no first-hand familiarity with the generated code at all. When the tool was initially written, only one compiler was available. The developers, then, essentially set up the trigger initialization with the knowledge of how the compiler would initialize the state variable, and they never gave it a second thought.
Who’s at fault in this situation— anybody, everybody, or nobody? That’s a tough call, as this problem could have been corrected in one of several ways. First, the tool could provide a setup screen where initial states can be set by project. This would always set the state of a trigger to a known value independent of any compiler vendor. So, we could say this is a problem of the tool vendor.
Second, the compiler that allowed non-ANSI-compliant code to be compiled should have generated warnings or errors depending on how the compiler settings were set. But even so, the tool used does not provide a screen for setting command line arguments by setting. It passes the command line directly to the compiler. So, we could say this problem belongs to the compiler vendor.
In the end, this problem illustrates some of the areas where more work is needed to ensure the quality of code generated automatically by any tool. We cannot assume that a tool that generates code will account for differences such as this one when going from one compiler to another or even from one compiler version to another. And, we certainly can’t assume the developer will have any first-hand knowledge of the generated code in a situation where automatic code generation is used.
There is no substitute for solid design, thorough testing, and experience when developing these types of tools. A good knowledge of human factors will help eliminate these types of holes during product design. The hand of an experienced design engineer will also weigh in to eliminate these types of holes in the design, making it much less likely to have this type of problem.
In this case, my years of experience helped me quickly determine and fix the problem without any help from the tool or the manufacturers. A younger or less experienced person, though, may not have been so lucky.