Обнаружьте адресную арифметику с указателями из-за LARGEADDRESSAWARE

Я хотел бы переключить свое приложение на LARGEADDRESSAWARE. Одной из проблем для наблюдения за является адресная арифметика с указателями, поскольку различие в указателе больше не может быть представлено, как подписано 32b.

Есть ли некоторый путь, как найти автоматически все экземпляры вычитания указателя в большом проекте C++?

В противном случае есть ли некоторые "наименьшее количество усилия" ручной или полуавтоматический метод, как достигнуть этого?

8
задан Suma 23 June 2010 в 08:01
поделиться

4 ответа

Поскольку наш код уже компилируется в GCC, я думаю, что самым быстрым способом будет:

  • собрать GCC
  • создать пользовательскую модификацию GCC, чтобы он выводил предупреждение (или ошибку) при обнаружении вычитания указателей
  • собрать проект и собрать все предупреждения о вычитании указателей

Вот схема изменений, которые нужно сделать в GCC для этого:

Добавить ваши предупреждения в:

  • c-typeck. c (функция pointer_diff)
  • cp/typeck.c (функция pointer_diff).

Кроме непосредственного обнаружения вычитания указателей, можно также обнаружить случаи, когда вы сначала преобразовываете указатели к интегральным типам, а затем вычитаете их. Это может быть сложнее в зависимости от того, как структурирован ваш код, в этом случае regexp-поиск (. intptr_t). -.*-(.*intptr_t) сработал достаточно хорошо.

0
ответ дан 6 December 2019 в 00:05
поделиться

PC-Lint может решить эту проблему.

См. http://gimpel-online.com/MsgRef.html , код ошибки 947:

Оператор вычитания применяется к указателям. - Выражение форма p - q была найдена, где и p, и q являются указателями. Это из особенно важно в случаях, когда максимальный указатель может переполнить тип, содержащий различия указателей. Например, предположим, что максимальный указатель составляет 3 гигабайта -1, и что различия указателей представлены длинным, где максимум long - 2 гигабайта -1. Обратите внимание, что обе эти величины подходят в 32-битном слове. Затем вычитая маленький указатель из очень большой указатель даст очевидное отрицательное значение в long, представляющий разницу указателя. Наоборот, вычитание очень большого указателя из маленького указателя может привести к положительное количество.

3
ответ дан 6 December 2019 в 00:05
поделиться

Это проблема, только если у вас есть 2 указателя, расстояние между которыми превышает 2000 миллионов байтов (2 ГБ). Это означает, что вы:

  • либо имеете очень большие массивы (> 2 ГБ)
  • , либо вы вычитаете указатели, указывающие на совершенно разные структуры

Так что ищите эти особые случаи.

Я думаю, что в большинстве случаев это не проблема.

0
ответ дан 6 December 2019 в 00:05
поделиться

Скомпилируйте код с 64-битным компилятором и включенным Wp64.

Поскольку указатели имеют 64-битную ширину, а int, long, DWORD и т.д. остаются 32-битными, вы получаете предупреждения за замыкание ptrdiff_t на int32_t

1
ответ дан 6 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: