Home > Programming > Silent promotions

Silent promotions

A few days ago I came across a bit of nasty behaviour when evaluating an expression performing a simple calculation on a signed and unsigned integer. Take the following C++ code snippet:

unsigned int nA = 10;
int nB = 11;

if( nA – nB < 0 )
{
// etc…
}

On first inspection, given the inputs I would expect the expression to evaluate to true. What surprised me is that, despite no compiler warnings being emitted using Visual Studio 2010 at warning level 4, the statement evaluates to false.

It turns out the signed int is silently promoted to an unsigned int which changes things. The answer to 10 – 11 is no longer -1 but 4294967294 ( or UINT_MAX-1 ) since an unsigned integer can’t hold a negative number (no ‘spare’, top bit for sign indication) and has wrapped around.

There are a few different fixes depending on the what your function is trying to do. Assuming mixing signed and unsigned types is unavoidable, the following fix to this is simple assuming there can be no range violations and you won’t end up with a large negative number for the left hand side:

if( static_cast( nA ) – nB < 0 )

I understand that gcc does emit a warning about this with -Wextra but the usual advice of test test test is hard to beat. Did I mention that I’m a huge fan of unit tests?

About these ads
Categories: Programming Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: