Bugs in Programming


Introduction Webster's Collegiate Dictionary includes the following definition of bug: "an unexpected defect, fault, flaw, or imperfections." In programming jargon, “errors” are known as “bugs”. There are many apocryphal stories about the origin of this term and how it got applied to programming. In the most popular story, Grace Murray Hopper discovered that the Harvard Mark II computer was producing incorrect answers. When she examined the machine more closely, trying to locate the problem, she found a squashed moth, which was caught between the contacts of an electromechanical relay, preventing the relay from fully closing; ergo, the first computer bug. In fact, she extracted the moth with a pair of tweezers and taped it into the operator's logbook with the comment “First actual bug found” -implying that the term was already in use at that time. Other stories about the first use of “bug” abound, so perhaps we shall never know the true entomology of this word.

The term bug became popular in programming to save the egos of programmers who could not admit that their programs were full of errors. Instead, they preferred to say that their programs had bugs in them. Actually, the metaphor is apt: programming bugs are hard to find; and although a located bug is frequently easy to fix, it is difficult to ensure that all the bugs have been removed from a program.

Debugging is the name that programmers give to the activity of locating and removing errors from programs (once the errors are known to exist, from testing the program). A programmer who is testing a program is often looking for new bugs to correct.

Classifying Bugs This section classifies bugs into five broad categories, each illustrated via an analogy that should help clarify its nature. Knowing the names of our enemies is the first step toward defeating them, so in the paragraphs below we define and explain the terms token error, syntax error, syntax constraint error, execution error, and intent error.

You might ask, “Why spend so much time talking about bugs when they should never occur?” The answer to this question is that programming requires an inhuman amount of precision, and although bugs should not occur in principle, they occur frequently in practice. Instead of expecting to write a completely correct program, we should expect to write a partially correct program. Then, we must become adept at quickly finding and fixing bugs by hand simulating our programs. Whenever we change a program, we should be able to prove that at least one bug has been removed, and that our program has become more correct. It is common for novice programmers to change programs randomly, and as a result make them less correct. Avoid this temptation: debug your programs by carefully analyzing them, making only proven corrections.

Token Errors A token error occurs whenever our program contains a word or symbol that is not in Java's vocabulary. As an analogy, suppose that one day we are standing on a street in San Francisco, and are asked by a lost motorist, “How can I get to Portland, Oregon?” If we say, “Just keep gngoi for ihegt hundred semil,” we would have committed multiple token errors. The motorist is unable to follow our instructions, because he is unable to decipher some of the words from which the instructions are composed. Similarly, the Java compiler must recognize each token (identifier, symbol, literal, and comment) in our programs.

Syntax Errors Even though the Java compiler may recognize every token in a program, the program still may contain a syntax error. This type of error occurs whenever we use incorrect grammar or punctuation (according to the syntax rules of the Java programming language). Going back to our lost motorist, we might reply, “For keep hundred miles going eight just.” Here, each word/token is individually recognizable as correct English, but we have combined them in a senseless and convoluted manner: the parts of speech are not in their correct positions for English grammar.

Syntax Constraint Errors These errors occur when the Java compiler cannot determine the meaning of a program. Sometimes a sentence might seem syntactically correct but, meaningless; for example, “Colorless green ideas sleep furiously.” Suppose that we told the motorist, “Keep going for eight hundred just miles.” Technically, this sentence is syntactically correct: we can use the word “just” an adjective meaning righteous —as in the sentence, “He is a just man.” But while the phrase “just man” is meaningful, the phrase “just miles” is meaningless. So once again, the motorist would not be able to understand fully what we told him.

If a program contains any token, syntactic, or syntax constraint errors, the Java compiler will discover them. In all three cases, the Java compiler has no idea of what we meant to say, so it will not try to correct the error; it will simply report the problem (as best as it can) in the Errors & Warnings window and be unable to finish compiling the program.

All these errors are called compile-time errors, because the Java compiler detects them while compiling our programs. We can link and run only programs that contain no compile-time errors. Errors that occur when the program is running (or executing) are called run-time errors. Since the compiler points out compile-time errors, they are much easier to fix.

Execution Errors Execution errors occur when the Java runtime system is executing a program and discovers that it can't legally carry out one of our instructions (for example, dividing by 0). If it recognizes such a case, it terminates execution of the program (again, supplying some information about the error). Returning to our motorist trying to get from San Francisco to Portland, we might tell him to, “Just keep going for eight hundred miles”. But, if he happens to be facing west at the time, and interprets our instructions literally, he could travel only a few miles before reaching the Pacific Ocean. At this point he would stop (we hope) and realize that he could not complete our instructions as given. This illustrates an execution error.

Execution errors are often called run-time errors, because the Java runtime system can detect them only when it tries to execute or run a program.

Intent Errors The final error class is the most insidious, because neither the Java compiler or runtime system can detect this type of error when it occurs. An intent error occurs whenever Java successfully completes execution of a program, but the program doesn't compute the correct answer. Coming back to our motorist who is trying to reach Portland from San Francisco; we could again tell him, “Just keep going for eight hundred miles.” But if this time he happened to be facing south, he could successfully carry out our instructions to completion, but he would end up in Tijuana, Mexico not Portland, Oregon.

Remember that Java understands neither our programs or what we indended to do with them. It knows only how to compile, link and execute the instructions that we give it. There is no way for Java to know what we intend the program to do, or detect that our program did not accomplish what we intended it to do.

Frequently, intent errors occur early in our programs and then later lead to execution errors. In such cases, the error becomes manifest at a location that is different than the source of the error. Thus, we must carefully hand simulate our programs, either from the beginning, or backward from the execution error or end of the program, to locate the incorrect instructions.


Footnotes

Grace Murray Hoppen Grace Murray Hopper (1907–1992) was a mathematician who joined the Navy as a WAVE during World War II. During her wartime service she was a programmer who worked on the Harvard series of computers —the first general-purpose American stored-program computer. After the war she joined the Remington Rand Corporation, but also continued to be active in the Navy. During the 50s and 60s she worked on the development of compilers in general, and in particular on the programming language COBOL, which is used still extensively for business programming.

She retired from the Navy in 1986, having reached the rank of a Rear Admiral. Throughout her lifetime she was an active lecturer and educator; in her honor, the Association of Computing Machinery (ACM) has named a prize for innovative software developed by young computer scientists. There is also a ship named in her honor by the Navy.

On the origin of Bugs: the OED In fact, the Oxford English Dictionary cites a 1889 newspaper quotation that said, "Mr. Edison, I was informed, had been up the two previous nights discovering 'a bug' in his phonograph."