Предупреждение о целочисленном переполнении только при использовании ключевого слова const

Я получаю предупреждение с ключевым словом const в C++ при использовании clang++ v. 17.0.1 или более поздней версии с флагом -Winteger-overflow. Вот фрагмент кода:

int foo_const()
{
    const auto min = std::numeric_limits<int>::min(); // const keyword
    return - min; // warning: overflow in expression; result is -2147483648 with type 'int' [-Winteger-overflow]
}

int foo()
{
    auto min = std::numeric_limits<int>::min();   // no const keyword
    return - min; // no warning
}

В функции foo_const я получаю предупреждение о потенциальном целочисленном переполнении. Однако та же операция в неконстантной функции foo компилируется без предупреждения.

Я был бы признателен за помощь в понимании того, почему ключевое слово const вызывает предупреждение о переполнении в этом конкретном случае.

Я думаю, что переполнение происходит в следующей строке return - min;

john 04.04.2024 10:40

Без ключевого слова const кажется, что оно допускает возможность переназначения min более высокому значению, которое не переполняется при отрицании.

Barmar 04.04.2024 10:41

верно. Я поместил комментарий к предыдущей строке, потому что ключевое слово const вызывает такое поведение. Комментарии поменяю, спасибо.

Daniele Pallastrelli 04.04.2024 10:41

«Я был бы признателен за помощь в понимании того, почему ключевое слово const вызывает предупреждение о переполнении в этом конкретном случае». -- Я думаю, было бы интереснее понять, почему в другом случае не срабатывает предупреждение о переполнении. Поскольку переполнение, очевидно, происходит в обоих случаях.

JaMiT 04.04.2024 10:42

что говорит Джон: godbolt.org/z/YvaMPfhz1. В вопрос следует включить предупреждающее сообщение.

463035818_is_not_an_ai 04.04.2024 10:42

Интересно, что gcc ведет себя точно так же, предупреждая только в случае const.

n. m. could be an AI 04.04.2024 11:17

Стандарт C++ не требует, чтобы компилятор обнаруживал этот UB. То, что компилятор выполняет такую ​​​​проверку «ворса» и предупреждает о UB, является бонусом, даже если он делает это только в сценарии foo_const. Дезинфицирующее средство UB улавливает UB в обоих режимах.

Eljay 04.04.2024 13:11
const int обычно может быть повышен до constexpr int, что позволяет провести дальнейшую проверку.
Jarod42 04.04.2024 15:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
8
125
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Когда вы используете квалификатор const, компилятор автоматически заменит использование переменной исходным значением. Когда он пытается сделать это в выражении -min, результатом является значение, выходящее за пределы диапазона int.

В версии без const ссылка на min в операторе return обрабатывается нормально, а не заменяется начальным значением. Таким образом, нет никакого известного переполнения.

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

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

Swift - Friday Pie 04.04.2024 10:54

Короткий ответ: компилятор просто недостаточно умен. Обе функции приводят к одному и тому же UB.

Другие вопросы по теме

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

Как работает этот ручной индексатор строк C++?
C++ - Как нарисовать равнобедренный треугольник с правой стороной вверх с помощью рекурсии?
Почему выходной буфер по-прежнему очищается немедленно, а не ждет 10 секунд, пока он отобразится?
Неявно выбирать тип и размер элемента массива из косвенного параметра шаблона
Почему редактирование значения с использованием указателя, то есть частного поля класса, требует объявления дополнительной переменной?
Заставить существующий экземпляр Windows Explorer перейти в определенную папку
Аргумент типа `<метод класса C++>` несовместим с параметром типа `GLFWwindowsizefun` при использовании GLFW внутри класса
Как создать представление по диапазону ключей/значений?
C++23 выводит это
Почему приведение указателя члена объединения к указателю объединения не является UB, поскольку они могут иметь разный размер?