Я хотел бы переключить свое приложение на LARGEADDRESSAWARE. Одной из проблем для наблюдения за является адресная арифметика с указателями, поскольку различие в указателе больше не может быть представлено, как подписано 32b.
Есть ли некоторый путь, как найти автоматически все экземпляры вычитания указателя в большом проекте C++?
В противном случае есть ли некоторые "наименьшее количество усилия" ручной или полуавтоматический метод, как достигнуть этого?
Поскольку наш код уже компилируется в GCC, я думаю, что самым быстрым способом будет:
Вот схема изменений, которые нужно сделать в GCC для этого:
Добавить ваши предупреждения в:
pointer_diff
)pointer_diff
). Кроме непосредственного обнаружения вычитания указателей, можно также обнаружить случаи, когда вы сначала преобразовываете указатели к интегральным типам, а затем вычитаете их. Это может быть сложнее в зависимости от того, как структурирован ваш код, в этом случае regexp-поиск (. intptr_t). -.*-(.*intptr_t) сработал достаточно хорошо.
PC-Lint может решить эту проблему.
См. http://gimpel-online.com/MsgRef.html , код ошибки 947:
Оператор вычитания применяется к указателям. - Выражение форма p - q была найдена, где и p, и q являются указателями. Это из особенно важно в случаях, когда максимальный указатель может переполнить тип, содержащий различия указателей. Например, предположим, что максимальный указатель составляет 3 гигабайта -1, и что различия указателей представлены длинным, где максимум long - 2 гигабайта -1. Обратите внимание, что обе эти величины подходят в 32-битном слове. Затем вычитая маленький указатель из очень большой указатель даст очевидное отрицательное значение в long, представляющий разницу указателя. Наоборот, вычитание очень большого указателя из маленького указателя может привести к положительное количество.
Это проблема, только если у вас есть 2 указателя, расстояние между которыми превышает 2000 миллионов байтов (2 ГБ). Это означает, что вы:
Так что ищите эти особые случаи.
Я думаю, что в большинстве случаев это не проблема.
Скомпилируйте код с 64-битным компилятором и включенным Wp64.
Поскольку указатели имеют 64-битную ширину, а int, long, DWORD и т.д. остаются 32-битными, вы получаете предупреждения за замыкание ptrdiff_t на int32_t