Favorite (Clever) Defensive Programming Best Practices

Language Agnostic

Language Agnostic Problem Overview


If you had to choose your Favorite (clever) techniques for defensive coding, what would they be? Although my current languages are Java and Objective-C (with a background in C++), feel free to answer in any language. Emphasis here would be on clever defensive techniques other than those that 70%+ of us here already know about. So now it is time to dig deep into your bag of tricks.

In other words try to think of other than this uninteresting example:

  • if(5 == x) instead of if(x == 5): to avoid unintended assignment

Here are some examples of some intriguing best defensive programming practices (language-specific examples are in Java):

- Lock down your variables until you know that you need to change them

That is, you can declare all variables final until you know that you will need to change it, at which point you can remove the final. One commonly unknown fact is that this is also valid for method params:

public void foo(final int arg) { /* Stuff Here */ }

- When something bad happens, leave a trail of evidence behind

There are a number of things you can do when you have an exception: obviously logging it and performing some cleanup would be a few. But you can also leave a trail of evidence (e.g. setting variables to sentinel values like "UNABLE TO LOAD FILE" or 99999 would be useful in the debugger, in case you happen to blow past an exception catch-block).

- When it comes to consistency: the devil is in the details

Be as consistent with the other libraries that you are using. For example, in Java, if you are creating a method that extracts a range of values make the lower bound inclusive and the upper bound exclusive. This will make it consistent with methods like String.substring(start, end) which operates in the same way. You'll find all of these type of methods in the Sun JDK to behave this way as it makes various operations including iteration of elements consistent with arrays, where the indices are from Zero (inclusive) to the length of the array (exclusive).

So what are some favorite defensive practices of yours?

Update: If you haven't already, feel free to chime in. I am giving a chance for more responses to come in before I choose the official answer.

Language Agnostic Solutions


Solution 1 - Language Agnostic

In c++, I once liked redefining new so that it provided some extra memory to catch fence-post errors.

Currently, I prefer avoiding defensive programming in favor of Test Driven Development. If you catch errors quickly and externally, you don't need to muddy-up your code with defensive maneuvers, your code is DRY-er and you wind-up with fewer errors that you have to defend against.

As WikiKnowledge Wrote: > Avoid Defensive Programming, Fail Fast Instead. > > By defensive programming I > mean the habit of writing code that > attempts to compensate for some > failure in the data, of writing code > that assumes that callers might > provide data that doesn't conform to > the contract between caller and > subroutine and that the subroutine > must somehow cope with it.

Solution 2 - Language Agnostic

SQL

When I have to delete data, I write

select *    
--delete    
From mytable    
Where ...

When I run it, I will know if I forgot or botched the where clause. I have a safety. If everything is fine, I highlight everything after the '--' comment tokens, and run it.

Edit: if I'm deleting a lot of data, I will use count(*) instead of just *

Solution 3 - Language Agnostic

Allocate a reasonable chunk of memory when the application starts - I think Steve McConnell referred to this as a memory parachute in Code Complete.

This can be used in case something serious goes wrong and you are required to terminate.

Allocating this memory up-front provides you with a safety-net, as you can free it up and then use the available memory to do the following:

  • Save all the persistent data
  • Close all the appropriate files
  • Write error messages to a log file
  • Present a meaningful error to the user

Solution 4 - Language Agnostic

In every switch statement that doesn't have a default case, I add a case that aborts the program with an error message.

#define INVALID_SWITCH_VALUE 0

switch (x) {
case 1:
  // ...
  break;
case 2:
  // ...
  break;
case 3:
  // ...
  break;
default:
  assert(INVALID_SWITCH_VALUE);
}

Solution 5 - Language Agnostic

When you're handling the various states of an enum (C#):

enum AccountType
{
    Savings,
    Checking,
    MoneyMarket
}

Then, inside some routine...

switch (accountType)
{
    case AccountType.Checking:
        // do something

    case AccountType.Savings:
        // do something else

    case AccountType.MoneyMarket:
        // do some other thing

    default:
-->     Debug.Fail("Invalid account type.");
}

At some point I'll add another account type to this enum. And when I do, I'll forget to fix this switch statement. So the Debug.Fail crashes horribly (in Debug mode) to draw my attention to this fact. When I add the case AccountType.MyNewAccountType:, the horrible crash stops...until I add yet another account type and forget to update the cases here.

(Yes, polymorphism is probably better here, but this is just an example off the top of my head.)

Solution 6 - Language Agnostic

When printing out error messages with a string (particularly one which depends on user input), I always use single quotes ''. For example:

FILE *fp = fopen(filename, "r");
if(fp == NULL) {
    fprintf(stderr, "ERROR: Could not open file %s\n", filename);
    return false;
}

This lack of quotes around %s is really bad, because say filename is an empty string or just whitespace or something. The message printed out would of course be:

ERROR: Could not open file

So, always better to do:

fprintf(stderr, "ERROR: Could not open file '%s'\n", filename);

Then at least the user sees this:

ERROR: Could not open file ''

I find that this makes a huge difference in terms of the quality of the bug reports submitted by end users. If there is a funny-looking error message like this instead of something generic sounding, then they're much more likely to copy/paste it instead of just writing "it wouldn't open my files".

Solution 7 - Language Agnostic

SQL Safety

Before writing any SQL that will modify the data, I wrap the whole thing in a rolled back transaction:

BEGIN TRANSACTION
-- LOTS OF SCARY SQL HERE LIKE
-- DELETE FROM ORDER INNER JOIN SUBSCRIBER ON ORDER.SUBSCRIBER_ID = SUBSCRIBER.ID
ROLLBACK TRANSACTION

This prevents you from executing a bad delete/update permanently. And, you can execute the whole thing and verify reasonable record counts or add SELECT statements between your SQL and the ROLLBACK TRANSACTION to make sure everything looks right.

When you're completely sure it does what you expected, change the ROLLBACK to COMMIT and run for real.

Solution 8 - Language Agnostic

For all languages:

Reduce the scope of variables to the least possible required. Eschew variables that are just provided to carry them into the next statement. Variables that don't exist are variables you don't need to understand, and you can't be held responsible for. Use Lambdas whenever possible for the same reason.

Solution 9 - Language Agnostic

When in doubt, bomb the application!

Check each and every parameter at the beginning of each and every method (whether explictly coding it yourself, or using contract-based programming does not matter here) and bomb with the correct exception and/or meaningful error message if any precondition to the code is not met.

We all know about these implicit preconditions when we write the code, but if they are not explicitly checked for, we are creating mazes for ourselves when something goes wrong later and stacks of dozens of method calls separate the occurance of the symptom and the actual location where a precondition is not met (=where the problem/bug actually is).

Solution 10 - Language Agnostic

In Java, especially with collections, make use of the API, so if your method returns type List (for example), try the following:

public List<T> getList() {
    return Collections.unmodifiableList(list);
}

Don't allow anything to escape your class that you don't need to!

Solution 11 - Language Agnostic

in Perl, everyone does

use warnings;

I like

use warnings FATAL => 'all';

This causes the code to die for any compiler/runtime warning. This is mostly useful in catching uninitialized strings.

use warnings FATAL => 'all';
...
my $string = getStringVal(); # something bad happens;  returns 'undef'
print $string . "\n";        # code dies here

Solution 12 - Language Agnostic

C#:

string myString = null;

if (myString.Equals("someValue")) // NullReferenceException...
{

}

if ("someValue".Equals(myString)) // Just false...
{

}

Solution 13 - Language Agnostic

In c# checking of string.IsNullOrEmpty before doing any operations on the string like length, indexOf, mid etc

public void SomeMethod(string myString)
{
   if(!string.IsNullOrEmpty(myString)) // same as myString != null && myString != string.Empty
   {                                   // Also implies that myString.Length == 0
     //Do something with string
   }
}

[Edit]
Now I can also do the following in .NET 4.0, that additionally checks if the value is just whitespace

string.IsNullOrWhiteSpace(myString)

Solution 14 - Language Agnostic

In Java and C#, give every thread a meaningful name. This includes thread pool threads. It makes stack dumps much more meaningful. It takes a little more effort to give a meaningful name to even thread pool threads, but if one thread pool has a problem in a long running application, I can cause a stack dump to occur (you do know about http://www.latenighthacking.com/projects/2003/sendSignal/">SendSignal.exe</a>;, right?), grab the logs, and without having to interrupt a running system I can tell which threads are ... whatever. Deadlocked, leaking, growing, whatever the problem is.

Solution 15 - Language Agnostic

With VB.NET, have Option Explicit and Option Strict switched on by default for the whole of Visual Studio.

Solution 16 - Language Agnostic

With Java, it can be handy to make use of the assert keyword, even if you run production code with assertions turned off:

private Object someHelperFunction(Object param)
{
    assert param != null : "Param must be set by the client";

    return blahBlah(param);
}

Even with assertions off, at least the code documents the fact that param is expected to be set somewhere. Note that this is a private helper function and not a member of a public API. This method can only be called by you, so it's OK to make certain assumptions on how it will be used. For public methods, it's probably better to throw a real exception for invalid input.

Solution 17 - Language Agnostic

C++

#define SAFE_DELETE(pPtr)   { delete pPtr; pPtr = NULL; }
#define SAFE_DELETE_ARRAY(pPtr) { delete [] pPtr; pPtr = NULL }

then replace all your 'delete pPtr' and 'delete [] pPtr' calls with SAFE_DELETE(pPtr) and SAFE_DELETE_ARRAY(pPtr)

Now by mistake if you use the pointer 'pPtr' after deleting it, you will get 'access violation' error. It is far easier to fix than random memory corruptions.

Solution 18 - Language Agnostic

I didn't find the readonly keyword until I found ReSharper, but I now use it instinctively, especially for service classes.

readonly var prodSVC = new ProductService();

Solution 19 - Language Agnostic

In Java, when something is happening and I don't know why, I will sometimes use Log4J like this:

if (some bad condition) {
    log.error("a bad thing happened", new Exception("Let's see how we got here"));
}

this way I get a stack trace showing me how I got into the unexpected situation, say a lock that never unlocked, something null that cannot be null, and so on. Obviously, if a real Exception is thrown, I don't need to do this. This is when I need to see what is happening in production code without actually disturbing anything else. I don't want to throw an Exception and I didn't catch one. I just want a stack trace logged with an appropriate message to flag me in to what is happening.

Solution 20 - Language Agnostic

If you are using Visual C++, utilize the override keyword whenever you over-ride a base class's method. This way if anyone ever happens to change the base class signature, it will throw a compiler error rather than the wrong method being silently called. This would have saved me a few times if it had existed earlier.

Example:

class Foo
{
   virtual void DoSomething();
}

class Bar: public Foo
{
   void DoSomething() override { /* do something */ }
}

Solution 21 - Language Agnostic

I've learned in Java to almost never wait indefinitely for a lock to unlock, unless I truly expect that it may take an indefinitely long time. If realistically, the lock should unlock within seconds, then I'll wait only for a certain length of time. If the lock does not unlock, then I complain and dump stack to the logs, and depending on what is best for the stability of the system, either continue on as if the lock unlocked, or continue as if the lock never unlocked.

This has helped isolate a few race conditions and pseudo-deadlock conditions that were mysterious before I started doing this.

Solution 22 - Language Agnostic

C#

  • Verify non-null values for reference type parameters in public method.
  • I use sealed a lot for classes to avoid introducing dependencies where I didn't want them. Allowing inheritance should be done explicitly and not by accident.

Solution 23 - Language Agnostic

When you issue an error message, at least attempt to provide the same information the program had when it made the decision to throw an error.

"Permission denied" tells you there was a permission problem, but you have no idea why or where the problem occurred. "Can't write transaction log /my/file: Read-only filesystem" at least lets you know the basis on which the decision was made, even if it's wrong - especially if it's wrong: wrong file name? opened wrong? other unexpected error? - and lets you know where you were when you had the problem.

Solution 24 - Language Agnostic

In C#, use the as keyword to cast.

string a = (string)obj

will throw an exception if obj is not a string

string a = obj as string

will leave a as null if obj is not a string

You still need to take null into account, but that is typically more straight forward then looking for cast exceptions. Sometimes you want "cast or blow up" type behavior, in which case (string)obj syntax is preferred.

In my own code, I find I use the as syntax about 75% of the time, and (cast) syntax about 25%.

Solution 25 - Language Agnostic

Be prepared for any input, and any input you get that is unexpected, dump to logs. (Within reason. If you're reading passwords from the user, don't dump that to logs! And don't log thousands of these sorts of messages to logs per second. Reason about the content and likelihood and frequency before you log it.)

I'm not just talking about user input validation. For example, if you are reading HTTP requests that you expect to contain XML, be prepared for other data formats. I was surprised to see HTML responses where I expected only XML -- until I looked and saw that my request was going through a transparent proxy I was unaware of and that the customer claimed ignorance of -- and the proxy timed out trying to complete the request. Thus the proxy returned an HTML error page to my client, confusing the heck out of the client that expected only XML data.

Thus, even when you think you control both ends of the wire, you can get unexpected data formats without any villainy being involved. Be prepared, code defensively, and provide diagnostic output in the case of unexpected input.

Solution 26 - Language Agnostic

Java

The java api has no concept of immutable objects, which is bad! Final can help you in that case. Tag every class that is immutable with final and prepare the class accordingly.

Sometimes it is useful to use final on local variables to make sure they never change their value. I found this useful in ugly, but necessary loop constructs. Its just to easy to accidently reuse a variable even though it is mend to be a constant.

Use defense copying in your getters. Unless you return a primitive type or a immutable object make sure you copy the object to not violate encapsulation.

Never use clone, use a copy constructor.

Learn the contract between equals and hashCode. This is violated so often. The problem is it doesn't affect your code in 99% of the cases. People overwrite equals, but don't care about hashCode. There are instances in wich your code can break or behaves strange, e.g. use mutable objects as keys in a map.

Solution 27 - Language Agnostic

I try to use Design by Contract approach. It can be emulated run time by any language. Every language supports "assert", but it's easy and covenient to write a better implementation that let you manage the error in a more useful way.

In the Top 25 Most Dangerous Programming Errors the "Improper Input Validation" is the most dangerous mistake in the "Insecure Interaction Between Components" section.

Adding precondition asserts at the beginning of the methods is a good way to be sure that parameters are consistent. At the end of methods i write postconditions, that check that output is what's inteded to be.

In order to implement invariants, I write a method in any class that checks "class consistence", that should be called authomatically by precondition and postcondition macro.

I'm evaluating the Code Contract Library.

Solution 28 - Language Agnostic

I forgot to write echo in PHP one too many times:

<td><?php $foo->bar->baz(); ?></td>
<!-- should have been -->
<td><?php echo $foo->bar->baz(); ?></td>

It would take me forever to try and figure out why ->baz() wasn't returning anything when in fact I just wasn't echoing it! :-S So I made an EchoMe class which could be wrapped around any value that should be echoed:

<?php
class EchoMe {
  private $str;
  private $printed = false;
  function __construct($value) {
    $this->str = strval($value);
  }
  function __toString() {
    $this->printed = true;
    return $this->str;
  }
  function __destruct() {
    if($this->printed !== true)
      throw new Exception("String '$this->str' was never printed");
  }
}

And then for the development environment, I used an EchoMe to wrap things which should be printed:

function baz() {
  $value = [...calculations...]
  if(DEBUG)
    return EchoMe($value);
  return $value;
}

Using that technique, the first example missing the echo would now throw an exception ...

Solution 29 - Language Agnostic

C++

When I type new, I must immediately type delete. Especially for arrays.

C#

Check for null before accessing properties, especially when using the Mediator pattern. Objects get passed (and then should be cast using as, as has already been noted), and then check against null. Even if you think it will not be null, check anyway. I've been surprised.

Solution 30 - Language Agnostic

Use sentinel classes with certain interface based OOP patterns instead of null.

E.g. when using something like

public interface IFileReader {
  List<Record> Read(string file);
}

use a sentinel class like

public class NoReader : IFileReader {
  List<Record> Read(string file) {
    // Depending on your functional requirements in this case
    // you will use one or more of any of the following:
    // - log to your debug window, and/or
    // - throw meaningful exception, and/or
    return new List<Record>(); // - graceful fall back, and/or
    // - whatever makes sense to you here...
  }
}

and use it to initialize any IFileReader variable

IFileReader reader = new NoReader();

instead of just leaving them to null (either implicitly or explicitly)

IFileReader reader; /* or */
IFileReader reader = null;

to make sure you don't get unexpected null pointer exceptions.

Bonus: you don't really have to encase each and every IFileReader variable use with an if (var!=null) ... any more either because they won't be null.

Solution 31 - Language Agnostic

Use a logging system that allows dynamic, run time log level adjustments. Often if you have to stop a program to enable logging, you'll lose whatever rare state the bug occurred in. You need to be able to turn on more logging information without stopping the process.

Also, 'strace -p [pid]' on linux will show you want system calls a process (or linux thread) is making. It may look strange at first, but once you get used to what system calls are generally made by what libc calls, you'll find this invaluable for in the field diagnosis.

Solution 32 - Language Agnostic

Always compile at the highest warning level, and treat warnings as errors (build breakers).

Even if the code is "right" fix the cause of the warning without disabling the warning if at all possible. For example, your C++ compiler might give you a warning for legal code like this:

while (ch = GetNextChar()) { ... }

It looks like you might have typed = instead of ==. Most compilers that offer this (useful) warning will shut up if you add an explicit check.

while ((ch = GetNextChar()) != 0) { ... }

Being slightly more explicit not only silences the warning but also helps the next programmer who has to understand the code.

If you MUST disable a warning, use a #pragma in the code, so you can (1) limit the span of code for which the warning is disabled and (2) use comments to explain why the warning must be disabled. Warnings disabled in command lines or makefiles are disasters waiting to happen.

Solution 33 - Language Agnostic

when getting a table from a dataset

if(  ds != null &&
     ds.tables != null &&
     dt.tables.Count > 0 &&
     ds.tables[0] != null &&
     ds.tables[0].Rows > 0 )
{

    //use the row;
}

Solution 34 - Language Agnostic

For C++ : automatically detecting size of arrays

char* mystrings[] = { "abc", "xyz" , "pqr" }

typically then for is written like

for (int i=0; i< 3; i++)
{
    str= mystrings[i]
    // somecode
}

However, Later you may add new more strings to 'mystrings'. In that case, the for loop above may introduce subtle bugs in the code.

solution that i use is

int mystringsize = sizeof(mystrings)/sizeof(char*)
for (int i=0; i< mystringsize; i++)
{
    str= mystrings[i]
    // somecode
}

Now if you add more strings to 'mystrings' array, for loop will be automatically adjusted.

Solution 35 - Language Agnostic

My C++ guidelines, but I don't consider this to be clever:

  • Always lint, heck, make it part of your makefile. Better yet, use coverity if possible.
  • Don't use C++ exceptions.
  • Don't put too much stuff on C++ constructor. Use init() method instead. The only ways to signal an error in constructor is exceptions, which is PITA.
  • Don't overload operator unless it's necessary.
  • If your constructor has one argument, always use explicit keyword.
  • Avoid global objects. Their execution order is not guaranteed.
  • Define copy constructor when your class allocates a memory. But if you don't expect the class to be copied, and you're too lazy to define one, guard it from being called.


class NonCopied {
private:
NonCopied(const NonCopied&);
NonCopied& operator=(const NonCopied&);
}

  • Stop using sprintf(), strcpy(), strcat(). Use their replacement instead, eg. snprintf, strncpy(), etc.

Solution 36 - Language Agnostic

Use a console, like in games;

Not completely "defensive" but I got this from seeing it in a lot games.

I like to have a full console for all my applications which allow me to:

  1. Define simple commands to be invoked from the console (like swiching to debug mode, setting some runtime variables, check internal configuration parameters and so on).
  2. Access a log everytime I want from the application while application is running.
  3. Save the log to a file if needed
  4. Log every unhandled exception to the console before raising it to the user (if appropiate). That way every exception is caught as some level. If you combine this cleverly with debug information or a map file you can get excelent results.

In C# if you mark the Console methods with the Conditional Attribute then they will be automatically stripped from the release version. In other languages the same can be achieved through preprocessor directives.

I've found it to be specially valuable during testing phase as it allows the developer to see what's happening and the tester to provide better feedback to the developer.

In addition:

  • Never catch an exception just for loggin.
  • Never catch general exceptions (exception E)
  • Never hide exceptions
  • Treat compiler warnings as if they were errors, only accept a warning with a very careful study.
  • Always check every input coming from outside the library.
  • Check the input coming from inside the library in "debug", don't check in release.
  • Never raise a generic exception. If an exception exists that describe the problem use it, if don't, create your own.

Solution 37 - Language Agnostic

In C++ assert() is a very handy tool. I do not only provide it with the condition to evaluate but also with a message stating what's wrong:

assert( isConditionValid && "ABC might have failed because XYZ is wrong." );

When there is no actual variable to check or you find yourself in a situation that should never have occured ('default' handler of switch()) this works too:

assert( 0 && "Invalid parameter" );

It not only asserts in debug mode but also tells you what went wrong at the same time.

I got this from the "C++ Coding Standards" if I remember correctly.

Solution 38 - Language Agnostic

In Python, if I stub out (or change a method) and then don't have time to test it that day, I cram in an "assert False" so that the code will crash if the method is run, creating embarrassing errors I'll notice the next day. An intentional syntax error can be helpful as well.

Example:

def somefunction(*args,**kwargs):
    ''' <description of function and args> '''
    # finish this in the morning
    assert False, "Gregg finish this up"

Solution 39 - Language Agnostic

  • Tiny understandable classes. Many of them.
  • Tiny understandable Methods.
  • Immutable wherever possible.
  • Minimize scope--nothing public that can be package, nothing package that can be private.
  • never any excuse for a public mutable variable.

Also, when your classes are tiny and generally final, being defensive is really cheap--might as well throw it in regardless of if you believe in it or not. Test the values being passed to your constructors and (if you really MUST have them) setters.

Solution 40 - Language Agnostic

Remember that exceptions are a programmer's best friends - never eat them!

Solution 41 - Language Agnostic

In Perl, die() when subroutines aren't passed enough parameters. This prevents you from getting failures that you have to trace back up 10 levels through the stack.

sub foo {
    my $param0 = shift or confess "param0 is a required param";
    my $param1 = shift or confess "param1 is a required param";
    my $param2 = shift or confess "param2 is a required param";
    ...
}

Solution 42 - Language Agnostic

Design your logging strategy so that when an error occurs in production, the appropriate support person or developer is emailed automatically. This allows you to proactively find bugs, rather than waiting for users to complain.

Note that this should be done with some caution. One example I had was that a developer had written some logging code inside a loop. After a few months an error in the system triggered this code. Unfortunately the application sat in that loop, logging the same error over and over again. We arrived in the office that morning to be informed that our mail server had crashed after our logging framework sent 40,000 emails between the hours of 4am and 8am!

Solution 43 - Language Agnostic

In C++

I spread out asserts all over my functions, especially at start and end of functions to catch any unexpected input/output. When I later add more functionality in a function the asserts will help me remember. It also helps other people to see the intention of the function and are only active in debug mode.

I avoid pointers as much as possible and instead use references, that way I don't need to put cluttering if (NULL!=p)-statements in my code.

I also use the word const as often as I can both in declarations and as function/method arguments.

I also avoid using PODs and instead use STL/Boost as much as possible to avoid mem leaks and other nasty things. However I do avoid using too much custom defined templates as I find them hard to debug, especially for others who didn't write the code.

Solution 44 - Language Agnostic

Back to those days where RAM was not free, most computers were very limited and "NOT ENOUGH MEMORY !" was a pretty common error message...

Well, most application were then able to crash with 'elegance' : users (almost) never lost their works.

(Almost, I said ! ^^).

How was it done ? Very simple : when you app starts, allocate a balloon of RAM (say, a whopping 20 KB!). Then, when a call to malloc() fails :

  1. Say kindly that there is "NOT ENOUGH MEMORY" (this message was mandatory).
  2. Add "And you better save all your work. Now!"
  3. Release the whopping 20 KB balloon of RAM.
  4. Resume.

Et voilĂ . Your app is crashing slowly at the user, most of the time, can save it's work.

Solution 45 - Language Agnostic

Try not to build anything you design for a few weeks. Often other scenarios will come to you then before things get locked in.

Solution 46 - Language Agnostic

  • Make your code as readable as possible, especially by using function and variable names that are as obvious as possible. If this means that some names are a bit on the long side, then so be it.

  • Use a static analyser as much as possible. You soon get into the habit of writing code that conforms to its rules.

  • During development, make it easy to turn on diagnostic output - but make it easy to turn them off for production.

Solution 47 - Language Agnostic

Don't pass around naked collections, even generics. They cannot be protected and they cannot have logic attached to them.

A good parallel would be having a public variable instead of setter/getter. the setter/getter allows you to change your underlying implementation without effecting the outside world.

How do you change your data structure without effecting the outside world if you are passing around a collection? All the access for your collection is distributed throughout all your code!!

Instead, wrap it and give yourself a place to put a little business logic. You'll find some nice refactors once you've done so.

Often you'll find it makes sense to add some variables and maybe a second collection--then you'll realize this class has been missing all along!

Solution 48 - Language Agnostic

When doing multi-threaded C/C++ programming, create a series of macros that assert your function is being called on the thread you think its being called on. Then use them liberally.

  • ASSERT_ON_UI_THREAD
  • ASSERT_ON_WORKER_THREAD
  • ASSERT_ON_THREADPOOL_THREAD
  • ASSERT_ON_DOWNLOAD_THREAD
  • etc.

Use GetCurrentThreadId() on Windows or pthread_self() on Posix when the thread is initialized, then store in globals. The asserts compare against the stored value.

Has saved me LOTS of painful debugging, especially when someone else refactors existing multi-threaded code.

Solution 49 - Language Agnostic

If (some really bad condition) Then
Throw New Exception("particular bad thing happened")
End If

Usually this takes the form

Public SUb New (key As Guid)
Dim oReturn As returnpacket = Services.TableBackedObjectServices.GetData(key)
If oReturn.ds.tables(0).Rows.Count = 0 then Throw New Exception("TableBackedObject loaded from key was not found in the database.")
End If

Since that particular constructor is only supposed to be called when loading a particular object after selecting it from the results of a search procedure, not finding it is either a bug or a race condition (which would mean another user deleted the object by key).

Solution 50 - Language Agnostic

Some things I do in PHP (where mistakes are easy and often catastrophic):

  • Turn on all the syntax highlighting cues in Vim. There's a lot turned off by default (do :help php to see them). I'm thinking of adding a few error-highlighting things of my own...
  • Using a pre-commit hook in git to syntax-check (php -l) every changed file. It only prevents basic errors getting in, but it's better than nothing.
  • Writing wrappers around the database classes to make parameterised prepared statements brain-dead easy compared to typing out normal queries - $db->q1($sql, $param1, $param2) to fetch a single column of the first row, and so on.
  • Configuring it (via the Xdebug extension) to spit out gigantic HTML tables of debug info for even trivial warning messages, so it's impossible to ignore them. On the dev server, that is. On production they get silently logged instead.
  • Making things short, simple and obvious. I spend a lot of time just refactoring stuff for the sake of making smaller files.
  • Using the explicit control structure syntax to avoid having several "}"s in close proximity.
  • Proofreading code before it's checked in. I've got into a habit of maximising the window, then setting an absurdly large font size. If I can only make sense of it when I can see 132C x 50R on screen at once in a tiny font, it's too long to begin with.

Solution 51 - Language Agnostic

In c# usage of TryParse instead of Parse for value types to avoid exceptions like FormatException, OverflowException etc, of course to avoid writing the try block for the same.

Bad code

string numberText = "123"; // or any other invalid value

public int GetNumber(string numberText)
  {
  try
  {
     int myInt = int.Parse(numberText);
     return myInt;
  }
  catch (FormatException)
  {
    //log the error if required
     return 0;
   }
  catch (OverflowException)
  {
     return 0;
  }
}

Good code (if you don't want to handle errors)

string numberText = "123"; // or any other invalid value
public int GetNumber(string numberText, int defaultReturnValue)
  {
    int myInt;
    return ( int.TryParse(numberText, out myInt) ) ?  myInt : defaultReturnValue;
}

You can do the same for almost all the value types e.g: Boolean.TryParse, Int16.TryParse, decimal.TryParse etc

Solution 52 - Language Agnostic

In C#: Instead of this:

if( str==null )

Do this:

if( String.IsNullOrEmpty(str) )

Solution 53 - Language Agnostic

In C#, use 'using' to make sure object is disposed when it goes out of scope. i.e.

        using(IDataReader results = DbManager.ExecuteQuery(dbCommand, transaction))
        {
            while (results.Read())
            {
                //do something
            }
        }

Also, check for null values after casting

        MyObject obj = this.bindingSource.Current as MyObject;
        if (MyObject != null)
        {
           // do something
        }

Also, I use enums whenever possible to avoid hardcoding, typos and to provide easy renaming if required, i.e.

	private enum MyTableColumns
{ 
	UserID,
	UserName
}

private enum StoredProcedures
{
	usp_getMyUser,
	usp_doSomething
}

public static MyUser GetMyUser(int userID)
{
	List<SqlParameter> spParameters = new List<SqlParameter>();

	spParameters.Add(new SqlParameter(MyTableColumns.UserID.ToString(), userID));


	return MyDB.GetEntity(StoredProcedures.usp_getMyUser.ToString(), spParameters, CommandType.StoredProcedure);
}

Solution 54 - Language Agnostic

Include high-level exception handling, as described in detail here

http://richnewman.wordpress.com/2007/04/08/top-level-exception-handling-in-windows-forms-applications-part-1/">Top-level Exception Handling in Windows Forms Applications

My Program.cs would then look like this

    static class Program
    {
    [STAThread]
    static void Main()
    {
        Application.ThreadException += 
            new ThreadExceptionEventHandler(new ThreadExceptionHandler().ApplicationThreadException);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }

    public class ThreadExceptionHandler
    {
        public void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

Solution 55 - Language Agnostic

Don't use single-character variables for loop indexes. For example:

for (int ii = 0 ; ii < someValue ; ii++)
    // loop body

This is a simple habit, but it's very helpful if you have to use a standard text editor for find references to the loop variable. Of course, indexed loops typically shouldn't be so long that you need to search for the index references ...

Solution 56 - Language Agnostic

C++:

Avoid raw pointers, always use the Boost smart pointer package (e.g., shared_ptr).

Solution 57 - Language Agnostic

I do a lot of math in my work testing mixed signal semiconductors on Automatic Test Equipment from Teradyne (c, vba), Advantest(c++ .net), and the like.

Two defensive maneuvers I use are:

  • prevent division by zero, if (x!=0) { z=y/x; } else { /* give z a recognizable fake number, continue program */ }

  • don't pass zero or negative numbers to log calculations. This is common for calculations of gain, CMRR, and PSRR. if (x>0) { psrr = 20 * log (x); } else { psrr = -999 ; /*fake number */ }

Some may argue against using fake numbers, but these programs are used in very high volume semiconductor manufacturing. If an error happens while testing a bad part, it is better to continue testing and to keep the integrity of the data format. The fake numbers are easily separated as outliers during post-processing of test data.

-- mike

Solution 58 - Language Agnostic

JavaScript:

We should use "==" and "===" appropriately.

> == : type-converting equality comparison > > === : strict equality comparison

For example, '1'==1 is true, but '1'===1 is false.

Many people use "==" instead of "===" unconsciously.

Solution 59 - Language Agnostic

If there's a value type that has certain constraints on its value, make a class where those constraints are enforced by code. Some examples:

public class SanitizedHtmlString
{
private string val;

public SanitizedHtmlString(string val)
{
  this.val = Sanitize(val);
}

public string Val
{
  get { return val; }
}

//TODO write Sanitize method...
}


public class CarSpeed
{
private int speedInMilesPerHour; 

public CarSpeed(int speedInMilesPerHour)
{
  if (speedInMilesPerHour > 1000 || speedInMilesPerHour < 0)
  {
    throw new ArgumentException("Invalid speed.");
  }
  this.speedInMilesPerHour = speedInMilesPerHour; 
}

public int SpeedInMilesPerHour
{
  get { return speedInMilesPerHour; }
}
}

Solution 60 - Language Agnostic

[Crash-Only software][1], in short instead of requiring some shutdown procedure along with some seldomly used (and hence probably buggy) recovery code, always stop the program by "crashing it" and thus always run the recovery code when starting.

This is not applicable to everything, but in some cases it's a very neat idea.

[1]: http://www.usenix.org/events/hotos03/tech/full_papers/candea/candea_html/index.html "Crash-Only software"

Solution 61 - Language Agnostic

So, who among us hasn't accidentally locked up Visual Studio for a while when writing a recursive method?

  int DoSomething(int value)  // stupid example for illustrative purposes
  {
      if (value < 0)
          return value;
      value++;  // oops
      return DoSomething(value);
  }

To avoid the annoyance of having to wait, and sometimes potentially having to kill off your IDE with task manager, include this in your recursive method while you're debugging it:

  int DoSomething(int value)
  {
>>    if (new StackTrace().FrameCount > 1000)  // some appropriately large number
>>        Debug.Fail("Stack overflow headed your way.");

      if (value < 0)
          // some buggy code that never fires
      return DoSomething(value);
  }

This may seem like it would be slow, but in practice checking the FrameCount is quite fast (less than a second on my PC). You can take this failsafe out (or maybe just comment it out, but leave it for later debugging) after you're sure the method is working properly.

Solution 62 - Language Agnostic

Language agnostic: Do never rely on compilers, virtual machines, etc. regarding initialisation. Always initialise your variables explicitly to helpful values.

Assertions are your best friend, although unit testing could fit better in some cases.

C/C++: Use stack based objects whenever possible.

In conditionals, check explicitly for the value that you expect or don't expect. For example if you have a boolean variable called activated instead of writing if (activated) write if (true == activated). The reason is that activated might contain garbage good enough to make the conditional succeed.

Solution 63 - Language Agnostic

Not needing to contend with the language's limitations is the best defense I can employ in my program's logic. Sometimes it is easier to state when things should stop.

For example you have this kind of loop:

while(1)
{
  // some codes here

  if(keypress == escape_key || keypress == alt_f4_key 
     || keypress == ctrl_w_key || keypress == ctrl_q_key) break;

  // some codes here
}

If you want to put the condition on loop header, instead of battling the language for not having an until construct, just copy the condition verbatim and put an exclamation mark:

while(! (keypress == escape_key || keypress == alt_f4_key 
     || keypress == ctrl_w_key || keypress == ctrl_q_key) )
{ 
    // some codes here
}

There's no until construct on C-derived languages, so just do the above, otherwise do this(possible in C/C++, use #define ;-)

until(keypress == escape_key || keypress == alt_f4_key 
     || keypress == ctrl_w_key || keypress == ctrl_q_key)
{ 
    // some codes here
}

Solution 64 - Language Agnostic

Rather then var.equals("whatever") in java I do "whatever".equals(var). That way, if var is null I don't have to worry about a nullpointer exception. That works great when dealing with things like URL parameters, etc.

Solution 65 - Language Agnostic

Hardly clever, but a decent practice, perhaps. In C/C++:

Always return from a function at the bottom, never in the middle. The sole exception to this is a check for null on required arguments; that always comes first and immediately returns (otherwise I'd just be writing a big "if" condition at the top which just looks silly).

int MyIntReturningFuction(char *importantPointer)
{
    int intToReturn = FAILURE;
    if (NULL == importantPointer)
    {
        return FAILURE;
    }
    // Do code that will set intToReturn to SUCCESS (or not).
    return intToReturn;
}

I have seen a lot of arguments for why it doesn't really matter, but the best argument for me is simply experience. Too often I've scratched my head, asking "Why the heck doesn't my break point near the bottom of this function get hit?" only to find that someone other than me had put a return somewhere above (and usually changing some condition that should have been left alone).

I've also found that having very simple rules like this makes me a much more consistent coder. I never violate this rule in particular, so sometimes I have to think of alternative ways of handling things (such as cleaning up memory and such). So far, it has always been for the better.

Solution 66 - Language Agnostic

  • When executing SQL queries from your code, always use placeholders
  • MySQL has a useful non-standard extension of the DELETE statement: DELETE FROM sometable WHERE name IS LIKE 'foo%' LIMIT 1. This way you won't wipe the whole table in case of mistake.

Solution 67 - Language Agnostic

Language agnostic : issue : reporting and dealing with portions of a whole. Whenever calculations and percentages are bing displayed, I always keep a running total and for the last entry its value is not calculated like the rest, but by subtracting the running total from 100.00. In this fashion, if some interested party chooses to add up all the componenet percentages they will add exactly to 100.00

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRyan DelucchiView Question on Stackoverflow
Solution 1 - Language AgnosticJoe Soul-bringerView Answer on Stackoverflow
Solution 2 - Language AgnosticJohn MacIntyreView Answer on Stackoverflow
Solution 3 - Language AgnosticLeopardSkinPillBoxHatView Answer on Stackoverflow
Solution 4 - Language AgnosticDiomidis SpinellisView Answer on Stackoverflow
Solution 5 - Language AgnosticRyan LundyView Answer on Stackoverflow
Solution 6 - Language AgnosticNik ReimanView Answer on Stackoverflow
Solution 7 - Language AgnosticamsimmonView Answer on Stackoverflow
Solution 8 - Language AgnosticdkretzView Answer on Stackoverflow
Solution 9 - Language AgnosticpeSHIrView Answer on Stackoverflow
Solution 10 - Language AgnosticDavid GrantView Answer on Stackoverflow
Solution 11 - Language AgnosticEric JohnsonView Answer on Stackoverflow
Solution 12 - Language AgnosticChristian C. SalvadóView Answer on Stackoverflow
Solution 13 - Language AgnosticBinoj AntonyView Answer on Stackoverflow
Solution 14 - Language AgnosticEddieView Answer on Stackoverflow
Solution 15 - Language AgnosticChrisAView Answer on Stackoverflow
Solution 16 - Language AgnosticOutlaw ProgrammerView Answer on Stackoverflow
Solution 17 - Language AgnosticNitin BhideView Answer on Stackoverflow
Solution 18 - Language AgnosticJMSView Answer on Stackoverflow
Solution 19 - Language AgnosticEddieView Answer on Stackoverflow
Solution 20 - Language AgnosticSteve RoweView Answer on Stackoverflow
Solution 21 - Language AgnosticEddieView Answer on Stackoverflow
Solution 22 - Language AgnosticBrian RasmussenView Answer on Stackoverflow
Solution 23 - Language AgnosticJoe McMahonView Answer on Stackoverflow
Solution 24 - Language AgnosticMatt BriggsView Answer on Stackoverflow
Solution 25 - Language AgnosticEddieView Answer on Stackoverflow
Solution 26 - Language AgnosticraupachView Answer on Stackoverflow
Solution 27 - Language AgnosticZenView Answer on Stackoverflow
Solution 28 - Language Agnostictoo much phpView Answer on Stackoverflow
Solution 29 - Language AgnosticmmrView Answer on Stackoverflow
Solution 30 - Language AgnosticpeSHIrView Answer on Stackoverflow
Solution 31 - Language AgnosticdicroceView Answer on Stackoverflow
Solution 32 - Language AgnosticAdrian McCarthyView Answer on Stackoverflow
Solution 33 - Language AgnosticJohn BokerView Answer on Stackoverflow
Solution 34 - Language AgnosticNitin BhideView Answer on Stackoverflow
Solution 35 - Language AgnosticKOkonView Answer on Stackoverflow
Solution 36 - Language AgnosticJorge CórdobaView Answer on Stackoverflow
Solution 37 - Language AgnosticvobjectView Answer on Stackoverflow
Solution 38 - Language AgnosticGregg LindView Answer on Stackoverflow
Solution 39 - Language AgnosticBill KView Answer on Stackoverflow
Solution 40 - Language AgnosticVectorView Answer on Stackoverflow
Solution 41 - Language AgnosticEric JohnsonView Answer on Stackoverflow
Solution 42 - Language AgnosticdavogonesView Answer on Stackoverflow
Solution 43 - Language AgnosticAndersKView Answer on Stackoverflow
Solution 44 - Language AgnosticSylvain RodrigueView Answer on Stackoverflow
Solution 45 - Language AgnosticJas PanesarView Answer on Stackoverflow
Solution 46 - Language AgnosticSteve MelnikoffView Answer on Stackoverflow
Solution 47 - Language AgnosticBill KView Answer on Stackoverflow
Solution 48 - Language Agnostici_am_jorfView Answer on Stackoverflow
Solution 49 - Language AgnosticJoshuaView Answer on Stackoverflow
Solution 50 - Language Agnosticuser42092View Answer on Stackoverflow
Solution 51 - Language AgnosticBinoj AntonyView Answer on Stackoverflow
Solution 52 - Language AgnosticDSOView Answer on Stackoverflow
Solution 53 - Language AgnosticEvgenyView Answer on Stackoverflow
Solution 54 - Language AgnosticEvgenyView Answer on Stackoverflow
Solution 55 - Language AgnostickdgregoryView Answer on Stackoverflow
Solution 56 - Language AgnosticView Answer on Stackoverflow
Solution 57 - Language AgnosticMikeView Answer on Stackoverflow
Solution 58 - Language AgnosticgraygerView Answer on Stackoverflow
Solution 59 - Language AgnosticRossFabricantView Answer on Stackoverflow
Solution 60 - Language AgnosticjannebView Answer on Stackoverflow
Solution 61 - Language AgnosticRyan LundyView Answer on Stackoverflow
Solution 62 - Language AgnosticsakiskView Answer on Stackoverflow
Solution 63 - Language AgnosticMichael BuenView Answer on Stackoverflow
Solution 64 - Language AgnosticChad OkereView Answer on Stackoverflow
Solution 65 - Language AgnosticAdamView Answer on Stackoverflow
Solution 66 - Language AgnosticEugene MorozovView Answer on Stackoverflow
Solution 67 - Language AgnosticguzzibillView Answer on Stackoverflow