I would like to switch my application to LARGEADDRESSAWARE. One of issues to watch for is pointer arithmetic, as pointer difference can no longer be represented as signed 32b.
Is there some way how to find automatically all instances of pointer subtraction in a large C++ project?
If not, is there some "least effort" manual or semi-automatic method how to achieve this?
PC-Lint can find this kind of problem.
Look at http://gimpel-online.com/MsgRef.html, error code 947:
Subtract operator applied to pointers
-- An expression of the
form p - q was found where both p and q are pointers. This is of
special importance in cases where the maximum pointer can
overflow the type that holds pointer differences. For example,
suppose that the maximum pointer is 3 Gigabytes -1, and that
pointer differences are represented by a long, where the
maximum
long is 2 Gigabytes -1. Note that both of these quantities fit
within a 32 bit word. Then subtracting a small pointer from a
very large pointer will produce an apparent negative value in the
long representing the pointer difference. Conversely,
subtracting a very large pointer from a small pointer can produce
a positive quantity.
Compile the code with a 64 bit compiler and Wp64 turned on.
Because pointers are 64bit wide, but int, long, DWORD etc. stay 32 bit wide, you get warnings for shorting a ptrdiff_t to a int32_t
This is only a problem if you have 2 pointers that are more than 2000 million bytes (2GB) apart. This means that you:
- either have very large arrays (> 2GB)
- or you are subtracting pointers that point to totally different structures
So look for these special cases.
I think that in most cases this is not a problem.
As our code already compiles with GCC, I think perhaps the fastest way might be:
- build a GCC
- create a custom modification of GCC so that it prints warning (or error) whenever pointer subtraction is detected
- build the project and gather all warnings about pointer subtraction
Here is the outline of changes which need to be done to GCC for this:
Add your warnings into:
- c-typeck.c (
pointer_diff
function)
- cp/typeck.c (
pointer_diff
function).
Besides of directly detecting pointer subtraction, another thing to do can be to detect cases where you first convert pointers to integral types and then subtract them. This may be more difficult depending on how is your code structured, in out case regexp search for (.intptr_t).-.*-(.*intptr_t) has worked quite well.