Предупреждения об устаревании библиотеки GLM вокруг volatile в C++20

Многие операции с volatile устарели в c++20 (см. https://en.cppreference.com/w/cpp/language/cv)

Итак.... когда я использовал очень популярную библиотеку glm (https://github.com/g-truc/glm) в своем проекте, я получил предупреждения об этом коде (файл type_half.inl)

GLM_FUNC_QUALIFIER float overflow()
{
    volatile float f = 1e10;

    for(int i = 0; i < 10; ++i)
        f *= f; // this will overflow before the for loop terminates
    return f;
}

Этот код используется для принудительного переполнения с плавающей запятой, и, очевидно, volatile здесь используется для отключения оптимизации вокруг f. В противном случае компилятор может просто выкинуть этот цикл за ненадобностью.

Как этот код можно исправить для современных стандартов С++, таких как С++ 20 и выше?

Отключить предупреждение? (Компилятор должен сказать вам, какой флаг использовать в командной строке)

Paul Sanders 20.04.2023 13:15

вы можете заменить использование volatile с помощью std:atomic

Kozydot 20.04.2023 13:17

Отключение предупреждений - очень плохая практика!! Это абсолютно не вариант. @ПолСандерс

fsmoke 20.04.2023 13:26

std:atomic - тяжеловес для этого, так как вдобавок нет необходимости в потокобезопасности или барьерах

fsmoke 20.04.2023 13:32

Проверьте это и выбросьте volatile, никогда не было безопасно использовать его для отключения оптимизации. stackoverflow.com/questions/40122141/… Также вас может заинтересовать реализация DoNotOptimize google/benchmark: github.com/google/benchmark/blob/main/include/benchmark/…

Fabian Keßler 20.04.2023 14:47

Отключение предупреждений - очень плохая практика!! Это абсолютно не вариант. Вы бы сделали это только для тех файлов, которые в этом нуждаются... Смотрите также: stackoverflow.com/questions/3378560/…

Paul Sanders 20.04.2023 15:53

@fsmoke: Есть ли какая-то причина, по которой функция просто не возвращает numeric_limits<float>::infinity(), поскольку именно это происходит, когда вы переполняете число с плавающей запятой IEEE-754?

Nicol Bolas 20.04.2023 16:31

@EricPostpischil, предупреждение: составное присваивание с «изменчивым» левым операндом устарело [-Wvolatile]

fsmoke 20.04.2023 16:43

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

fsmoke 20.04.2023 16:47

Отключение предупреждений - очень плохая практика" Работа с абсолютами - плохая практика. Да, я бы не стал отключать его глобально, но отключать его для определенного файла или строк можно.

HolyBlackCat 20.04.2023 19:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Очевидное решение — удалить *=: f = f * f;. Код не требует особого поведения вне *=; он просто хочет, чтобы компилятор не оптимизировал операции умножения. В той мере, в какой volatile заставляет компилятор делать это, он будет работать так же хорошо с f = f * f;.

ДА это работает!! предупреждения теперь подавлены! спасибо

fsmoke 20.04.2023 17:01

@fsmoke: вы должны отправить это в репозиторий GLM Github в качестве запроса на выпуск / вытягивание.

Nicol Bolas 20.04.2023 17:04

да думаю завтра(сейчас вечер - я уже устал) создам новый pull-request в glm repo

fsmoke 20.04.2023 17:11

хахаха - я только что клонировал основную ветку glm - и там это предупреждение уже исправлено - как вы предлагаете f = f * f :)))) - так что... все уже сделано, без нас

fsmoke 20.04.2023 18:10

"Очевидное решение" Можете ли вы объяснить очевидную часть? У меня может быть неправильная ментальная модель относительно разницы двух выражений (нет для тривиальных типов, таких как float)

MatG 20.04.2023 19:13

@MatG: я не понимаю. Вы, кажется, понимаете, что в этом случае нет никакой разницы между двумя выражениями, за исключением того факта, что одно является законным, а другое - допустимым, но устаревшим. Так что ... используйте легальный. Это очевидная часть. Весь смысл осуждения *= и ему подобных volatile состоит в том, чтобы дать понять, что вы знаете, что это не одна атомарная операция. f = f * f; проясняет это так, как f *= f; нет.

Nicol Bolas 20.04.2023 19:15

@MatG, разница между операциями такова: f*=f эта операция над lvalue - устарела, но f=f*f прямое назначение - разрешено новым стандартом. Внимательнее перечитайте cppreference в моем стартовом посте.

fsmoke 20.04.2023 19:54

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