java.sql.Date is not a real date

java.sql.Date stores only date information, not times. Simply converting a java.util.Date into a java.sql.Date will silently set the time to midnight. So, to store date/times to be manipulated as java.util.Date objects, don’t do this:

// BUG: loses time of day
preparedStatement.setDate(1, new java.sql.Date(date.getTime()));

do this instead:

preparedStatement.setTimestamp(1, new java.sql.Timestamp(date.getTime()));

java.sql.Timestamp extends java.util.Date, but it should not be used as a Date. In JDK 1.3.1, Timestamp.getTime() (inherited from Date) returns the time to the nearest second only, but JDK 1.4.2 and JDK 1.5 it returns the time to the nearest millisecond as expected. Continue reading “java.sql.Date is not a real date” →

Data access layer should be separate

In a multi-layered architecture, the data access layer should hide database foibles. For example, Oracle stores empty strings as null – this should be hidden in the data access layer by specifying function return values appropriately. For example, ensure that the layer never returns a null string: null strings returned from the database should be converted to empty strings. Continue reading “Data access layer should be separate” →

Oracle silently truncates dates

According to the documentation, the Oracle DATE type does not store fractions of a second. So if you store a date/time value including fractions of a second and read it back, you’ll get back a slightly different date/time. This will cause exact date matching code in your appplication to fail.

Oracle empty string = null

In Oracle 8, there is no such thing as a zero-length string. Any zero-length string, either from a function call or the literal '', is treated as null.

Some of the consequences of this are counterintuitive. Here are some examples. Continue reading “Oracle empty string = null” →

Don’t use automatically generated unique IDs

Think carefully before using an automatically-generated unique ID as a primary key in a SQL table. Using such automatically-generated IDs introduces extra implementation detail. This is a pain to manage, especially if they are used as primary keys or worse, foreign keys in tables. Continue reading “Don’t use automatically generated unique IDs” →

Visual C++ exception handling

This article describes a problem with the default handling of exceptions in Microsoft’s Visual C++ compilers. The problem is caused by the compiler’s extension to the C++ exception handling mechanism. I then give a technique that properly exploits this extension, bringing it into line with normal C++ exception handling. This allows programs to deal with exceptions that are normally very difficult to handle, such as memory access violations.

This article was originally based on Visual C++ 6, and the same issues exist in the Visual Studio .NET C++ compiler. Finally, after at least six years, Microsoft fixed the fundamental problem in Visual C++ 2005. But to fully take advantage of this, it’s still necessary to implement an exception translation scheme like the one described in this article.

Win32 hardware exceptions

Under Visual C++, certain exceptional runtime conditions can be treated something like C++ exceptions. These exceptions are raised by the OS for events like memory access violations, division by zero, and so on. A (presumably) full list is in Microsoft’s MSDN Library under “EXCEPTION_RECORD”.

They are referred to in the documentation as “hardware exceptions”, “C exceptions”, “structured exceptions” and “C structured exceptions”. Actually, they are neither C-specific nor structured (at least compared to C++ exceptions). I refer to them as “Win32 hardware exceptions” or just “Win32 exceptions” because they are specific to the Win32 operating systems and hardware on which they run.

Visual C++ programs may be unstable by default

Visual C++ is a good compiler. But, like all compilers, it has some bad features. The default handling of Win32 exceptions in pre-2005 versions is one of them.

Continue reading “Visual C++ exception handling” →

Prefer prefix operators over postfix

Whenever you have a choice, you should use the C++ prefix increment and decrement operators (e.g. ++i) instead of the postfix versions (e.g. i++). This will make your code more efficient, clear and consistent. This advice applies (more or less) to most languages that have both prefix and postfix operators.

1. Efficiency

Code like this is quite common:

for (i = 0; i < count; i++)
    // stuff

But consider what’s going on. The expression i++ has a value, namely the value of i before the increment. i is incremented during evaluation of the expression, but the program must keep a copy of the un-incremented i to use as the value of the expression.

Continue reading “Prefer prefix operators over postfix” →

Clarifying C++ negation

The C++ negation operator (!) can be hard to see in code listings, and this leads to bugs. Here are a few solutions to this perennial coding problem.

The C negation operator (!) is used by most C++ programmers also. The trouble with it is that it can be hard to see. For example, code like this Continue reading “Clarifying C++ negation” →

Disappearing C++ functions

C++ specifies how compilers should deal with programs that misbehave. This article describes one of the effects of these rules: compilers may generate no code for the body of a misbehaved function, whether or not the function is ever called.

Consider this function

void furphy()
{
    std:::cerr << "furphy";
    int* p = 0;
    *p = 0; // dereferencing a null pointer causes undefined behaviour
}

What code will a compiler generate for the body of this function? In particular, may the compiler elide (generate an empty body for) the function?

The answer is that, according to the C++ standard, a compiler can generate any code at all, or none at all, for the body of this function. This is true even if the compiler can’t tell whether the function is ever called. It’s even true if there is no way at all to tell this.

Continue reading “Disappearing C++ functions” →