Получение предупреждений о неявном переполнении преобразования из неподписанного в подписанное - PullRequest
0 голосов
/ 22 октября 2018

Рассмотрим следующий проблемный код:

#include <iostream>

void foo(int64_t y) {
    std::cout << y << "\n";
}

int main() {
    uint64_t x = 14400000000000000000ull;
    foo(x);
}

Обычно печатает -4046744073709551616.

Как можно заставить компилятор помочь с этим типом проблемы преобразования / переполнения?Я пробовал следующее:

g++ -g overflow.cpp -fsanitize=undefined -Wall -Wextra -pedantic -Wconversion -Wconversion
clang++ -g overflow.cpp -fsanitize=undefined,integer,implicit-conversion -Wall -Wextra -pedantic

Ни один из которых не дает никакого предупреждения во время компиляции или во время выполнения.

(clang версия 7.0.0, gcc версия 8.2.1)

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Проблема здесь в том, что -Wconversion будет только предупреждать, если значение, возвращаемое обратно к типу источника, может не совпадать с типом.Например, если вместо foo будет взято int, то -Wconversion выдаст предупреждение, поскольку возможно, что вы не можете привести значение в int к исходному значению uint64_t.Если у нас есть

uint64_t u = some_value;
int64_t s = static_cast<int64_t>(u);
uint64_t check = static_cast<uint64_t>(s)

, то check == u всегда будет истинным (если int64_t также является комплиментом для двоих), поэтому -Wconversion не выдаст предупреждение, потому что мы вернем исходное значение.

В этом случае вам понадобится

-Wsign-conversion

, который предупредит вас о несоответствии знаков.

0 голосов
/ 22 октября 2018

GCC и Clang имеют опцию предупреждения -Wsign-преобразование, чтобы выдавать предупреждение в подобных случаях.

предупреждение: неявное преобразование изменений подписи: 'uint64_t' (он же «unsigned long»)в 'int64_t' (он же 'long') [-Wsign-преобразование]

Обратите внимание на документацию GCC о -Wconversion

... Предупреждения о преобразованиях между подписанным и неподписаннымцелые числа по умолчанию отключены в C ++, если -Wsign-преобразование явно не включено.

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

...