Go to top

Why A + B != A - (-B) ?

, 1 Apr 2012
 Rate this:
While developing analyzer intended for detecting 64-bit errors, I sometimes encounter interesting ways of code behavior

While developing analyzer intended for detecting 64-bit errors, I sometimes encounter interesting ways of code behavior. I would like to show you one example that is not very interesting practically but might be helpful in understanding more complicated cases.

```char *A = "123456789";
unsigned B = 1;
char *X = A + B; // X: "23456789"
char *Y = A - (-B); // Y: <Bad Ptr>```

If we compile the 32-bit version of the code, the expressions "A + B" and "A - (-B)" will be equivalent. In the 32-bit code, the pointers X and Y point to the second item of the array A. To understand it better look at the Figure 1 showing the process of calculating "A - (-B)".

But when we compile the 64-bit code, the expressions "A + B" and "A - (-B)" mean absolutely different things. The subexpression "-B" has an unsigned type and equals 0xFFFFFFFFu. And it is this value 0xFFFFFFFFu that is subtracted from the pointer (see Figure 2).

The shown error leads to an access outside the array on a 64-bit system. Such errors might occur when working with negative indexes when 32-bit unsigned variables are used to store them. Here is an example:

```unsigned Index = -1;
Array[Index] = Z;```

Like in the previous case, the expression "Array[Index] = Z;" works well in the 32-bit program but leads to an error in the 64-bit one.

Conclusion:

You should avoid using unsigned data types to store negative values. If the variables used to access array items can take negative values, use only signed data types, for example "int". Or rather use the types size_t and ptrdfiff_t.

Share

Architect Program Verification Systems, Co Ltd
Russian Federation

Andrey Karpov is technical manager of the OOO "Program Verification Systems" (Co Ltd) company developing the PVS-Studio tool which is a package of static code analyzers integrating into the Visual Studio development environment.

PVS-Studio is a static analyzer that detects errors in source code of C/C++ applications. There are 3 sets of rules included into PVS-Studio:

Awards: MVP, Intel Black Belt

Andrey Karpov is also the author of many articles on the topic of 64-bit and parallel software development. To learn more about the PVS-Studio tool and sources concerning 64-bit and parallel software development, please visit the www.viva64.com site.

Best Articles:

E-mail: karpov@viva64(dot)com

You may also be interested in...

Why “Good Enough” Isn’t Good Enough Anymore for Software Configuration Management

 First Prev Next
 unsigned is a modifier, not a type Daniele Rota Nodari 3-Apr-12 0:03
 I guess the problem may arise due to incorrect (or ambigous) usage of a type modifier (unsigned) without a type.   unsigned B does not explicitly tells what type B is, but only that B will have no sign and the type being the compiler integer default type, so the type is chosen by the compiler.   As of http://en.cppreference.com/w/cpp/language/types[^] it seems that `unsigned B` is treated as 32 bit `unsigned int B`   This may obviously depend on compiler and compiler options.   So have You performed the same test declaring B using explicit type declaration (int or long or long long or __int64, ecc.)?
 Re: unsigned is a modifier, not a type Karpov Andrey 3-Apr-12 0:38
 Re: unsigned is a modifier, not a type Daniele Rota Nodari 3-Apr-12 3:44
 Re: unsigned is a modifier, not a type Karpov Andrey 3-Apr-12 20:10
 Last Visit: 31-Dec-99 18:00     Last Update: 22-Sep-14 21:18 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140922.1 | Last Updated 2 Apr 2012
Article Copyright 2012 by Karpov Andrey