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

Я только что присоединился к команде, которая имеет тысячи строк кода, таких как:

int x = 0;
x=something();
short y=x;
doSomethingImportantWith(y);

Компилятор выдает приятные предупреждения: «Преобразование значения типа бит XX в« короткий »вызывает усечение. Мне сказали, что нет случаев, когда действительно происходит усечение, но я серьезно сомневаюсь в этом.

Есть ли хороший способ вставить чеки в каждый случай, имеющий эффект:

if (x>short.max) printNastyError(__FILE,__LINE);

перед каждым назначением? Выполнение этого вручную займет больше времени и усилий, чем я хотел бы использовать, а написание сценария, который читает предупреждения и добавляет эти данные в правильный файл, а также необходимые включения, кажется излишним — тем более, что я ожидаю, что кто-то уже сделал это (или что-то подобное).

Меня не волнует производительность (на самом деле) или что-то другое, кроме как знать, когда возникают эти проблемы, поэтому я могу либо исправить только те, которые действительно имеют значение, либо я могу убедить руководство в том, что это проблема.

3

Решение

Вы можете попробовать скомпилировать и запустить его со следующим уродливым хаком:

#include <limits>
#include <cstdlib>

template<class T>
struct IntWrapper
{
T value;

template<class U>
IntWrapper(U u) {
if(u > std::numeric_limits<T>::max())
std::abort();
if(U(-1) < 0 && u < std::numeric_limits<T>::min()) // for signed U only
std::abort();
value = u;
}

operator T&() { return value; }
operator T const&() const { return value; }
};

#define short IntWrapper<short>

int main() {
int i = 1, j = 0x10000;
short ii = i;
short jj = j; // this aborts
}

Очевидно, это может нарушить код, который проходит short в качестве аргумента шаблона и, вероятно, в других случаях, поэтому определите его там, где он нарушает сборку. И вам может понадобиться добавить перегрузки операторов, чтобы обычная арифметика работала с оберткой.

5

Другие решения

Вероятно, вы можете написать плагин для gcc, чтобы обнаруживать эти усечения и отправлять вызов функции, которая проверяет, что преобразование безопасно. Вы можете написать эти плагины в С или же питон. Если вы предпочитаете использовать Clang, он также поддерживает запись плагины.

Я думаю, что самый простой способ сделать это — сделать так, чтобы плагин конвертировал небезопасный бросок из int в short вызвать функцию _convert_int_to_float_fail_if_data_loss(value), Я оставлю это в качестве упражнения для читателя, как написать такой плагин.

1

По вопросам рекламы [email protected]