The Artima Developer Community
Sponsored Link

Weblogs Forum
Offensive Coding

67 replies on 5 pages. Most recent reply: Sep 12, 2006 5:43 PM by Todd Blanchard

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 67 replies on 5 pages [ « | 1 ... 2 3 4 5 ]
Andy Dent

Posts: 165
Nickname: andydent
Registered: Nov, 2005

Re: Offensive Coding - asserts can be scanned Posted: Jul 30, 2006 4:11 AM
Reply to this message Reply
Advertisement
Just a data point from the C++ community.

One of the most effective projects I have worked on combined running PC-Lint in the nightly build with the results from that (and unit tests etc.) being emailed daily to everyone from the CEO downwards.

PC-Lint does the most amazing static analysis and will tell you where you need to have assertions for non-null parameters etc.

Thus, failure to properly add assertions results in a warning message in front of the boss.

Thomas Guest

Posts: 236
Nickname: tag
Registered: Nov, 2004

Re: Offensive Coding - asserts can be scanned Posted: Aug 1, 2006 12:38 AM
Reply to this message Reply
> Just a data point from the C++ community.
>
> One of the most effective projects I have worked on
> combined running PC-Lint in the nightly build with the
> results from that (and unit tests etc.) being emailed
> daily to everyone from the CEO downwards.
>
> PC-Lint does the most amazing static analysis and will
> tell you where you need to have assertions for non-null
> parameters etc.
>
> Thus, failure to properly add assertions results in a
> warning message in front of the boss.

Good point: getting a decent automated build/static analysis/test system going is hard (and especially so for C++) but, as we all know, well worth the effort. With very little extra effort, the results of all this automation can be published to everyone with a stake in the project -- which can really maximise the benefit.

David Rosenstrauch

Posts: 3
Nickname: darose
Registered: Sep, 2006

Re: Offensive Coding Posted: Sep 7, 2006 10:45 AM
Reply to this message Reply
> <pre>
> public String [] getParameters() {
> String [] result = new String[intParms.length];
> for(int n = 0; n < intParms.length; n++) {
> result[n] = "parameter " + intParms[n];
> }
> return result;
> }
>
> </pre>
>
> <p>If we don’t have any parameters, we return an empty
> array. The empty array is an example of a null object..
> an object which gracefully handles an exceptional case.
> Now that we're always returning a valid array, there's
> s one less possible error.</p>


It's easy to fix this situation when returning things like collections. That's because a "null object" for a collection is very easy to create - it's just a collection with no elements in it. Similarly for Strings, a null object is easy - it's just an empty string.

However, having read Bobby Woolf's paper on the NullObject Pattern some years ago, one of the key things I took away from it is that it can often be very difficult to create a null object implementation for many types of objects. Sometimes this is because, as Bobby's paper cited, it can be difficult to define exactly what the null behavior is. But sometimes also, some objects really don't lend themselves well to being null objects.

For example: look at this code:

<java>
public class Database {
public Record findRecord(Key key, Object keyValue) {
...
}
}
</java>

What exactly are we to return if the Record is not found on the database? The implication from this article is that we should return a NullRecord. But it's very difficult to implement "null" behavior on a Record. Most likely the Record object has methods to retrieve the data values for various columns, e.g.:

<java>
public interface Record {
public String getStringValue(String columnName);
public int getIntValue(String columnName);
...
}
</java>

But there's no way, for example, to return a "null int" from the getIntValue method.

And even for the case of getStringValue, I think it would be misleading to the developer to return any value, even the empty string. Returning an empty string would imply to the developer that the record was found, and that the value contained in that column was the empty string. That's obviously not correct, but there'd be no way using a NullRecord to distinguish between a record not found and a record containing nothing but empty strings for its values.

What else should it do then? Throw exceptions on every getXXXValue method? Bad design, IMO. You shouldn't have to wait until you start trying to query a DB record to find out that it wasn't found. You should have found out on the Database.findRecord() call.

But again, how do we indicate "not found" from the findRecord call? Since null object doesn't seem workable here, and we're trying to avoid returning nulls, then the only other option I can see is to throw an exception. But frankly, that's a poor design choice too, IMO. Having a record not be found is a very legitimate outcome of a find operation, IMO, and so you should not throw an exception - indicating an exceptional or error outcome - in a case like this.

Frankly, IMO, returning null is the right thing to do in a case like this - and probably in numerous other cases too for the same reasons.

Thoughts anyone?

DR

Sean Flanigan

Posts: 1
Nickname: seanf
Registered: Jan, 2003

Re: Offensive Coding Posted: Sep 8, 2006 1:40 AM
Reply to this message Reply
I think a <code>NullRecord</code> is quite workable.

Okay, the best you can do for a method that returns an <code>int</code> is probably a value like 0. Definitely not an exception. This might not sound like the ideal null implementation for <code>getIntValue()</code>, but if this were a null pointer, you wouldn't call <code>getIntValue()</code> anyway.

The trick is to make sure the caller checks for "nullness" at the right level of granularity. By the time you call <code>getXyzValue()</code>, it's too late. But the caller can check <code>record == Record.NULL</code> (or <code>record instanceof NullRecord</code>, if you have a strong stomach) just as easily as <code>record == null</code>.

Basically, returning <code>null</code> to indicate "no record found" is just a sentinel value. <code>Record.NULL</code> can be a sentinel value too. It's just a sentinel value that never causes a NullPointerException, among its other charms.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Offensive Coding Posted: Sep 8, 2006 5:12 AM
Reply to this message Reply
> I think a <code>NullRecord</code> is quite workable.
>
> Okay, the best you can do for a method that returns an
> <code>int</code> is probably a value like 0. Definitely
> not an exception. This might not sound like the ideal
> null implementation for <code>getIntValue()</code>, but if
> this were a null pointer, you wouldn't call
> <code>getIntValue()</code> anyway.
>
> The trick is to make sure the caller checks for "nullness"
> at the right level of granularity. By the time you call
> <code>getXyzValue()</code>, it's too late. But the caller
> can check <code>record == Record.NULL</code> (or
> <code>record instanceof NullRecord</code>, if you have a
> strong stomach) just as easily as <code>record ==
> null</code>.
>
> Basically, returning <code>null</code> to indicate "no
> record found" is just a sentinel value.
> <code>Record.NULL</code> can be a sentinel value too.
> . It's just a sentinel value that never causes a
> NullPointerException, among its other charms.


Yes, null records are workable. An isNull operation can be useful. Fact is, if you're writing an interface to get a record from a database you're going to need a something like a null record anyway for your tests. When I do similar design, I often have a class which returns default values and I subclass it and override individual methods for particular tests. You can make that your NullRecord.

Gregor Zeitlinger

Posts: 108
Nickname: gregor
Registered: Aug, 2005

Re: Offensive Coding Posted: Sep 9, 2006 6:52 AM
Reply to this message Reply
> But there's no way, for example, to return a "null int"
> from the getIntValue method.
You could return Integer - but I agree that you must be informed wheater the record was found before that.
Testing instanceof NullRecord is also silly.

There is another the NullRecord is problematic:
What sould the NullRecord return for primary key columns?
"", null, or 0. This would violate the invariant that the combination of all primary key columns is unique.

This leaves throwing an Exception and returning null (in findRecord):
Both are acceptable, IMHO.
nonOptional = db.getRecord(..)
if (nonOptional == null) {
  throw new Exception(..);
}
 
optional = db.getRecord(..)

vs.
nonOptional = db.getRecord(..)
 
try {
  optional = db.getRecord(..)
} catch (Exception e) {
  //ok, it's optional
}

Ryan Baker

Posts: 2
Nickname: nedruod
Registered: Sep, 2006

Re: Offensive Coding Posted: Sep 9, 2006 8:01 AM
Reply to this message Reply
You have to go with exotic things like XC# or Spec#, but even better is to have compiler verified NotNull specifications. That way you insure not only that errors don't happen if you program right, but that your chances of making a programming error are much lower.

I think the chance of developer error is the number one reason for the null check practice. Problem is it doesn't make things much better, you just get a better error message. Catching those problems at compile time however is best for everyone.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Depends on the language Posted: Sep 12, 2006 5:43 PM
Reply to this message Reply
And how it handles nil. I did a little thinking about that some time ago:

http://www.blackbagops.net/?p=73

Flat View: This topic has 67 replies on 5 pages [ « | 2  3  4  5 ]
Topic: Offensive Coding Previous Topic   Next Topic Topic: Hidden Variables

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use