My boss has always told me that a good programmer should be able to ensure that the code he or she changes is reliable, correct, and thoroughly self-verified; that you should completely understand all the results and impacts your changes will cause. I have tried my best to be this kind of programmer—by testing again and again—but bugs are still there.

How can I be a zero-bug programmer and know what every character of my code will cause and affect?

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. If this question can be reworded to fit the rules in the help center, please edit the question.

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. See the help center for guidance on writing a good question.

I used to have a co-worker who was favored by the boss because she consistently had a small bug count. How did she do it? Simple, she assigned the bugs she didn't want to someone else, and always took on the easiest/smallest features.
– tobyJan 30 '11 at 6:31

46

I don't know who first said it, but, "If debugging is the process of removing bugs, then programming must be the process of putting them in."
– Bruce AldermanJan 30 '11 at 7:03

8

Even better: become a boss and make your underlings feel miserable without having to take responsibility for anything.
– biziclopJan 30 '11 at 19:18

It's possible to get very close, but productivity suffers. And it's only worthwhile for certain high-risk software. The Space Shuttle software comes to my mind. But their productivity is of the order of a few lines a day. I doubt your boss wants that.

This software is bug-free. It is perfect, as perfect as human beings have achieved. Consider these stats: the last three versions of the program -- each 420,000 lines long - had just one error each. The last 11 versions of this software had a total of 17 errors.

Take the upgrade of the software to permit the shuttle to navigate with Global Positioning Satellites, a change that involves just 1.5% of the program, or 6,366 lines of code. The specifications for that one change run 2,500 pages, a volume thicker than a phone book. The specifications for the current program fill 30 volumes and run 40,000 pages.

What makes you think that FB is bug-free? Facebook's security and privacy model is one huge bug. For example, the Facebook bosses Facebook account got hacked last week due to security weaknesses.
– Stephen CJan 30 '11 at 2:06

Don't forget the moving goalposts. A feature in your PerfectProgram 1.0 can be a bug in 2.0
– CarlosJan 31 '11 at 12:41

4

@CodesInChaos: The theory says that there exist programs for which it is impossible to prove their behavior. It doesn't say that it is impossible to prove the behavior of all programs. I would guess that the majority of common programs are of the provable type, and claiming "It's impossible for my code to be bug-free because of the halting problem" is a misapplication of theory.
– endolithJan 23 '13 at 18:16

I'd be glad to prove that my code is working... but testing can only prove it's not. Are you talking formal proof or envisionning the debugging task here ?
– Matthieu M.Jan 30 '11 at 16:40

First useful answer in this thread. @Matthieu: You can prove for every possible combination of two bytes, that a function will return a correct result, (for example: max), which is a byte again. You can have two and more such functions, and now you can chain them, and get a big number of possible combination of such functions, which will again only ever produce a byte. The idea, that you only can prove something wrong is wrong. Popular, but wrong.
– user unknownMar 13 '11 at 4:19

@Matthieu M.: Testing proves that things are working the way you expect. If you can prove that all the items are working the way you expect, then from there you prove that you're dealing with input behaviour you didn't expect. Once you've nailed down what that behaviour is and what it should be, you write a new test for it. It's now part of your expected behaviour.
– dewordeOct 21 '11 at 10:49

1

@deworde: I understand the idea of testing, however apart from niche situations, the majority of the real work I've done could not be tested exhaustively, simply because the possible number of combinations was too big (and I'm not even adding timing issues). So, apart from niche situations, testing only go so far (it's still useful to check that at least the nominal case pass!)
– Matthieu M.Oct 21 '11 at 17:06

"avoid clever tricks like the plague" - this alone would make this good answer. As it is - it is great.
– BЈовићMay 21 '14 at 11:36

TDD

The point of TDD is that you don't write a single line of code if there is not a test requiring that line of code. And to take it to the extreme you always start developing a new feature by writing an acceptance test. Here I have found that writing cucumber style tests is ideal.

The TDD approach gives at least two benefits.

All code is written to solve a specific feature, thus no unnecessary overproduction.

Whenever you change an existing line of code, if you break a feature, you will be notified

It doesn't prove zero bugs, as that would be impossible (have already been pointed out by countless other answers). But after having learned TDD and become good at it (yes, it is also a skill that needs practice), I have a much higher confidence in my own code because it is thoroughly tested. And more importantly, I can change existing code I don't completely comprehend without worrying about breaking functionality.

But TDD doesn't help you all the way. You cannot write bug-free code if you do not thoroughly understand the architecture of the system, and the pitfalls of that architecture. E.g. if you are writing a web application that handles multiple requests simultaneously, you must know that you cannot share mutable data between multiple requests (don't fall into the newbie trap to cache mutable data to improve performance).

I believe that the development teams that are good at TDD deliver the code with the fewest defects.

The thing is, bugs are the things that you don't recognize. Unless you are have some kind of encyclopedic knowledge of the programming language/compiler as well as all of the environments your application will run in, you really cannot expect to produce 100% bug-free code.

You can reduce your bug count through lots of testing, but in the end there will likely be some fringe case that will not be accounted for. Joel Spolsky wrote a particularly nice article on bug-fixing.

Yes, it is impossible to never have a bug in your code but it's not impossible to have less bugs. The attitude that "That's dumb, You're always gonna have bugs" is just a cop out to avoid reducing the number of bugs in your code. No one is perfect but we can and should strive to be better. In my own efforts to improve I've found the following points helpful.

This is not easy. You will not improve over night. So don't get discouraged and don't give up.

Write less and write smarter. Less code is typically better code. It's natural to want to plan ahead and try to make awesome design patterns but in the long run just writing what you need saves time and prevents bugs.

Complexity is the enemy. Less does not count if it's an obscure complicated mess. Code golf is fun but it is hell to understand and a worse hell to debug. Whenever you write complicated code you open your self up to a world of problems. Keep things simple and short.

Complexity is subjective. Code that was once complicated becomes simple once you become a better programmer.

Experience matters. One of the two ways to become a better programmer is to practice. Practice is NOT writing programs you know how to write with ease, it's writing programs that hurt a little and make you think.

The other way to get better is to read. There are a lot of hard topics in programming to learn but you'll never be able to learn them by just programming, you need to study them. You need to read the hard stuff. Things like security and concurrency are impossible it learn correctly from just writing code unless you want to learn by cleaning up disasters. If you don't believe me look at the epic security issues sites like gawker had. If they took the time to learn how to do security correctly and not just make something that worked that mess would never have happened.

Read blogs. There are a ton of interesting blogs out there that will give you new and interesting ways to look at and think about programming this will help you to...

Learn the dirty details. The minor details of how obscure parts of your language and application work are very important. They could hold secrets that help you avoid writing complicated code or could be parts that have there own bugs you need to avoid.

Learn how the users think. Sometimes your users are flat out insane and will work with your app in ways you don't understand and can't predict. You need to get in to their heads enough to know the stranger things they might try and make sure your app can handle it.

Personally I think that striving for bug free programming seems to be more expensive (in both time and money). In order to reach zero bug, or even near-zero bug, you need to have the developers test thoroughly. This means regression test everything before submitting any code for patch review. This model doesn't strike me as being cost effective. Your better off having the developers conduct due diligent testing and leave the in-depth testing up to the QA team. Here is why:

Developers suck at testing. It's true and you know it. (I'm a developer!) A
good QA team will always find the edge cases that developers never think about.

Developers are good at coding. Let them get back to what they excel at (and usually what they prefer to do anyway.)

The QA team can find bugs related to multiple developer tasks in one pass.

Accept that when you write code, there will be bugs logged against it. That's why you have a QA process, and it's all part of being a developer. Of course this doesn't mean you submit something as soon as you write your last semi-colon. You still need to ensure quality in your work, but you can overdo it.

How many professions can you name that always get their task done right the first time without peer review and/or testing?

Zero bugs? It sounds like you need Lisp (follow the skeptic path and avoid the music video).

It is extraordinarily hard to achieve bug-free code in the mainstream coding environments (Java, C#, PHP, etc.). I would focus on producing well tested and peer-reviewed code in short controlled iterations.

Keeping the code as simple as you can will help you to avoid bugs.

Make sure that you are using code analysis tools (such as FindBugs, PMD and so on) which - combined with strict compiler warnings - will reveal all sorts of issues with your code. Take note of what they are telling you, really strive to understand what the nature of the bug is, and then take steps to change your programming idiom so that it feels unnatural to code in a manner that introduces that bug again.

Sometimes bugs are like hidden monsters living there, they hide during my repeatedly testing and self code review... but once I do peer-review, I found the monsters were unbelievable visible and jumped out to me suddenly. It's really weird. Depending only on human 'eye' and 'brain' seems impossible to touch the bug-free line. unit-test is not workable for all cases. Code analysis tools? sounds exciting, I've never used that, I will do research on that field.
– ElaineJan 30 '11 at 1:54

I would say you need Ada, but Lisp is more fun. ;-)
– OrblingJan 30 '11 at 2:40

1

@Elaine Where I work is a Java environment and code can only be shared with the team if it has passed through Findbugs and PMD. New team members pass through five stages: denial, anger, bargaining, depression and then acceptance. Afterwards they never look back.
– Gary RoweJan 30 '11 at 9:01

@Gary Rowe, I understand those reactions, lol, I've ever been in a company there was a QA dept., employees there weekly checked all the codes produced in that week, to see whether every lines of code conforms to the 'rule' (I have no idea about whether they were using some tools like Findbugs/PMD), but it sounds a little bit like the step that you're in.
– ElaineJan 31 '11 at 1:09

1

@Gary: No argument from me, but several places I've worked treat style violations as bug equivalents. And they tended to have style rules like "every class must declare static fields CLS_PKG and CLS_NAME that contain the package and class names". I generally support coding standards, but not when they devolve into stuff like that!
– TMNFeb 1 '11 at 14:45

All the "Don't code at all." answers are completely missing the point. Also, your boss does definitely not seem to be a moron!

I cannot recall how often I have seen programmers who simply did not know what their code does. Their sole development philosohpy seemed to be trial and error (and quite often also copy/paste/modify). While trial and error is a valid way to go about some problems, often you can analyze the problem domain and then apply a very specific solution based on your understanding of the tools you use and with a little bit of discipline and diligence you will have not only solved the problem but also most corner-cases (potential bugs) before you deploy it for the first time. Can you guarantee that the code is bug free? Of course not. But with every bug you encounter or read about you can add it to the things you might want to think about next time you write/change something. If you do this you will consequently gain a lot of experience on how to write code that is almost bug free. - There are tons of resources available on how to become a better programmer that can help you on the journey...

Personally, I would never commit code where I cannot explain every single line. Every line has a reason to be there, otherwise it should be removed. Of course sometimes you will make assumptions of the inner workings of the methods you call, otherwise you would need to know the inner logic of the whole framework.

Your boss is completely right to say that you should understand the results and impact of the code you write on existing system. Will bugs occcur? Yes, of course. But these bugs will be due to your incomplete understanding of the system/tools you work with and with every bug fix you will have better coverage.

"with every bug you encounter or read about you can add it to the things you might want to think about next time you write/change something" this is a great point. I created a google document related to bugs I've seen or coded, just for that purpose.
– BenDec 9 '11 at 20:28

As the other comments already correctly pointed out, there is no non-trivial software without bugs.

If you want to test the software always keep in mind, that tests can only prove the presence of bugs not their absence.

Depending on your domain of work you might try formal verification of your software.
Using formal methods you can become pretty sure that your software exactly meets the specification.

That ofcourse does not mean that the software exactly does what you want. Writing a complete specification is in almost all cases also not possible.
It basically shifts the place where errors can occur from implementation to specification.

So depending on your definition of "bugs" you can try formal verification or just try to find as many bugs as you can in your software.

You can strive to be a zero bug programmer. I strive to be a zero bug programmer whenever I'm writing code. However, I don't

engage multiple testing techniques (other that ATDD)

create formal verifications of our software

have a separate QA team

do hard analysis on each change made to the code base

use a language that leans more towards safety and caution

I don't do these things because they are cost prohibitive for the software I write. If I did these things I would probably be further along towards zero bugs, but it wouldn't make business sense.

I create internal tools that a large portion of our infrastructure use. My standards for testing and coding are high. However, there is a balance. I do not expect zero bugs because I can't have people put that kind of time into one piece of work. Things might be different if I were creating the software to control an X-Ray machine, jet engines, etc. No lives are on the line if my software breaks, so we don't engage in that level of assurance.

I would match the level of assurance to the intended use of the software. If you are writing code that the NASA shuttle will use maybe zero bug tolerance is reasonable. You just need to add a bunch of additional and very expensive practices.

I think a good first step towards becoming a "zero-bug" programmer is to change your attitude towards bugs. Instead of saying things "they happen," "get better QA and testers," or "developers suck at testing," say:

Bugs are not acceptable, and I will do everything within my power to eliminate them.

Once this becomes your attitude, the bugs will drop quickly. In your search to find ways to eliminate bugs, you'll come across test-driven-development. You'll find plenty of books, blog posts, and people offering free advice on better techniques. You'll see the importance of improving your skills through practice (like coding katas, or trying new things at home). You'll start to perform better at work because you'll start working on your craft at home. And, hopefully, once you see that it is possible to write good software, your passion for your craft will grow.

I have attained the "zero bug" status. I tell my users it's an un documented feature, or they are asking for a new feature and therefore it's an enhancement. If neither of these are accepted responses I merely tell them they have not understood their own requirements. Thus, there are no bugs. Programmers are perfect.

Never start coding unless you have UNAMBIGUOUS SPECIFICATIONS for your functionality.

DO NOT TEST or or if you do DO NOT RELY ON TESTING to catch defects in software.

Apply all FEEDBACK from defects discovered during testing, reviews and production to a process and developers who inserted defect in first place. Discard all defective components completely as soon as defects are found. Update your checklists and retrain your developers so they don't make mistakes like that again.

Testing can only prove that you have bugs, but it is usually useless to prove otherwise. Regarding the feedback - if you have coin-making machine that makes coins and every 10s coin on average has a defect. You can take that coin, flatten it up and insert into machine again. coin that made out that recycled blank will be not as good, but maybe acceptable. every 100s coin will have to be re-stamped 2 times and so on. Would it be easier to fix the machine?

Unfortunately people are not machines. To make good, defect-free programmer you have to invest a lot of time, training and iterating over every defect made. Developers need to be trained in formal verification methods which are often hard to learn and apply in practice. Economics of software development is also working against it - would you invest 2 years into training a programmer who can make fewer defects just to see him jumping to another employer? You can buy machine that make perfect coins, or hire 10 more code monkeys to create bunch of tests at same cost. You can perceive this exhaustive process as your "machine", your asset - investing in extensive training of excellent developers does not pay off.

Pretty soon you will learn how to develop software of acceptable quality, but probably you will never be one who is defect free for simple reason that there is no market for developer who makes perfect code because it is slow.

+1 for mentioning unambiguous specifications. I know this is a 2 year old topic, but I have to emphasize that yours is the only answer to point out that it is incorrect to assume that a bug equates to a programming failure.
– BrandonApr 8 '13 at 19:54

If someone follows the conventions of programming defensively, then changes will be easily traceable. Combine this with rigorous bug reports during development, and solid documentation, like with doxygen, and you should be able to know exactly what all of your code is doing and fix any bugs that come up, very efficiently.

Could this be a result of misunderstanding a good methodology, and not just generic boneheadedness?

What I mean is that it is possible that your boss heard of "zero defect methodology" (see section no.5), and didn't bother understanding what that meant?
Of course, it's inconvenient for management to postpone development of new features, in favor of bugs that you shouldnt have put in...
And of course, that threatens his bonus, so of course you wont get one because "good programmers don't have bugs"...

It's fine to make bugs, as long as you can find them and fix them (within reason, of course).

One of the fundamental concepts of software testing is that you can NEVER be absolutely sure that the program is perfect. You can validate it forever, but that never proves that the program is complete because it quickly becomes infeasible to even test against all input / variable combinations.

Your boss seems like one of those who "doesn't understand whats so hard about programming, since its just typing"

If we assume big software houses know how to get top notch developers (as in zero bugs programmer) we can deduct that Microsoft's software must be without bugs. Yet we know that's far from the truth.

The develop their software and when they reach certain level of low priority bugs they simply release the product and solve those later.

Unless you're developing something more complex than a simple calculator, It's not possible to avoid bugs all together. Hell even NASA has redundancy on their vehicles and bugs as well. Although they have much rigorous testing to avoid catastrophic failures. But nonetheless even they have bugs in their software.

Bugs are inevitable just as is human nature to err.

Having no bugs is like having a 100% secure system. If a system is 100% secure it definitely isn't useful any more (it probably lies inside tons and tons of concrete and isn't connected to the outside at all. Not wired nor wireless. So just as there are no perfectly secure system, there's no complex bug-less system.

I only see answers about us being human and prone to err, which is very true... but I see your question from another viewpoint.

I think you can write bug-free programs, but those typically are programs that you have written already 10 or 12 times. The 13th time you write the same program from scratch, you already know how to do it: you know the problem, you know the techniques, you know the libraries, the language... you see it in your mind. All the patterns are there, at all levels.

This happens to me with very simple programs because I teach programming. They are simple for me, but hard for the students. And I am not talking about solutions to problems I have done many, many times in the blackboard. Of course I know those. I mean ~300-line programs that solve something using concepts I know really well (the concepts I teach). I write these programs with no planning and they just work, and I feel I know all the details, I don't need TDD at all. I get a couple or three compilation errors (mostly typos and other things like that) and that's it. I can do this for small programs, and I also believe that some people can do that for more complicated programs. I think people like Linus Torvalds or Daniel J. Bernstein have such clarity of mind, they are the closest you can get to a bug-free coder. If you understand things deeply I think you can do it. I can only do this for simple programs, like I said.

My belief is that if you always try to do programs that are far above your level (I've spent years doing just that), you will get confused and make mistakes. Big mistakes like those in which you suddenly realise that your solution cannot work, when you finally understand the problem, and have to make changes so complicated that they might stop you from solving your problem or make the code awful. TDD is for this cases, I believe. You know that you don't grok the problem you are tackling and therefore put tests everywhere to make sure that you have a strong base. TDD doesn't solve the 10,000 feet vision, though. You might walk in circles with perfectly clean code all the time.

However, if you try to do something that is new but that is just above your level, you might get your program perfect or almost perfect. I think it is really difficult to know what programs are in your "knowledge frontier", but in theory that is the best way to learn. I rewrite programs from scratch a lot, actually. Some people do, but you need a lot of time and patience because the third time you repeat a non-trivial program you don't get excited like the first time.

So my advice is: don't think you understand something until you can write a program bug-free just for that thing. And then try to combine two of those concepts you know deeply into the same program. I'm almost sure you will get it right the first time. One of the best ways is to rewrite non-trivial software, something that took a lot of effort the first time (I am doing this with Android apps right now). Every time I start again I change something or add stuff, just to add a little fun, and I can tell you I get better and better and better... maybe not bug-free but really proud.

imho bugs and sudden, misterious algorithm artifacts must appear during the coding process: they inspire and force evolution of code.
however it's possible (usually after some testing) to check every variable that might be used before declaration, to handle every error wherever it may appear - to make the program zero-bug... until you recieve a request for a feature that was considered impossible when you were discussing program architecture ;)

I don't know--this sounds like kind of a mystical approach to programming, which is a distinctly non-mystical field of endeavor. You don't program effectively through trial and error or by using a divining rod. You design things intentionally. And bugs will still crop up. So you fix them. But first and foremost you intentionally design your code not to have bugs.
– CraigNov 23 '14 at 22:23

Maybe think more about the nature of the bugs that you get. If the bugs are generally minor oversights then a focus on better testing and a bit of code proof-reading would help.

If the bugs tend to be due to suboptimal programming decisions, though, then maybe putting more effort into better design is required. In this case, I think it's possible to be too dependent on testing to raise the quality of the software, because applying a patch to deficient code can just make future maintenance more complicated. On the one hand you get less bugs as you find and fix them, but on the other hand you prepare the ground for future bugs.

One way to judge if you have an issue with oversights or an issue with design might be to consider how much effort is required to fix the bugs. If the fixes tend to be large, or you feel that you don't understand them well, that points the figure at code design that can be improved.

That I think comes down to a sort of good taste about code, which you can develop with practice and review, and reading about people with similar problems.

Ultimately, it is futile to expect no bugs at all, but there's no harm in trying to reduce your bug count unless you already have it at some low level, and then it becomes a trade-off between your time and the time of whoever finds bugs that you don't catch.

In my opinion the best book to learn that is: GOOS. But of course a book is not enough. You need to go to some user group and discuss about this. Courses, conferences, etc. Zero-bugs quality is not easy.

First of all you need a boss who's really interested in high quality and willing to pay for it.

I agree that to be a zero-bug programmer you simply cannot program/code. It's part of every programmer's life to encounter and develop bug. No seasoned developer can say, hand on heart, they've never encountered a bug in their code.

Pair with another engineer. Write a failing test. Have every character you type be necessary to make the failing test pass. Refactor your code to make it simpler. Write another failing test, and so on an so forth.