1

Many operations with volatile were deprecated in c++20 (see https://en.cppreference.com/w/cpp/language/cv)

So.... when I used very popular glm library(https://github.com/g-truc/glm) in my project I got warnings around this code (file 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;
}

This code used to force causing floating point overflow, and obviously volatile here used to turn off optimization around f. Otherwise compiler can just throw out this cycle as useless.

How this code may be fixed for modern standards of c++, like c++20 and above?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
fsmoke
  • 135
  • 6
  • Turn off the warning? (The compiler should tell you what flag to use on the command line) – Paul Sanders Apr 20 '23 at 11:15
  • you can replace the usage of volatile using std:atomic – Kozydot Apr 20 '23 at 11:17
  • 1
    Turning off the warnings - is very bad practice!! It's absolutely not an option. @PaulSanders – fsmoke Apr 20 '23 at 11:26
  • std:atomic - heavyweight for this, as addition there is no need any thread safety or barriers – fsmoke Apr 20 '23 at 11:32
  • 1
    Check this out and throw the volatile away, it was never safe to use it to disable optimisations. https://stackoverflow.com/questions/40122141/preventing-compiler-optimizations-while-benchmarking Also, the implementation of DoNotOptimize of google/benchmark might interest you: https://github.com/google/benchmark/blob/main/include/benchmark/benchmark.h – Fabian Keßler Apr 20 '23 at 12:47
  • _Turning off the warnings - is very bad practice!! It's absolutely not an option._ You would only do it for the files that need it... See also: https://stackoverflow.com/questions/3378560/how-to-disable-gcc-warnings-for-a-few-lines-of-code – Paul Sanders Apr 20 '23 at 13:53
  • @fsmoke: Is there some reason the function doesn't just return `numeric_limits::infinity()`, since that's what happens when you overflow an IEEE-754 float? – Nicol Bolas Apr 20 '23 at 14:31
  • @EricPostpischil, warning: compound assignment with ‘volatile’-qualified left operand is deprecated [-Wvolatile] – fsmoke Apr 20 '23 at 14:43
  • @NicolBolas, it seems return value of this function always discarded - this functions used only for cause float overflow(i.e. generate FPU exception if such option is turned on) – fsmoke Apr 20 '23 at 14:47
  • *"Turning off the warnings - is very bad practice"* Dealing with absolutes is bad practice. I wouldn't disable it globally, yes, but disabling it for a specific file or lines is ok. – HolyBlackCat Apr 20 '23 at 17:31

1 Answers1

2

The obvious solution is to remove the *=: f = f * f;. The code doesn't specifically need any special behavior out of *=; it just wants to make the compiler not optimize the multiplying operations. To the extent that volatile makes the compiler do that, it would work just as well with f = f * f;.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • YES this works!! warnings now suppressed! Thanx – fsmoke Apr 20 '23 at 15:01
  • @fsmoke: You should submit this to the GLM Github repo as an issue/pull request. – Nicol Bolas Apr 20 '23 at 15:04
  • yes i think tomorrow(now evening - i already tired) i'll create new pull-request to glm repo – fsmoke Apr 20 '23 at 15:11
  • 1
    hahaha - i just now clone master branch of glm - and there this warning already fixed - as you suggest f = f * f :)))) - so... all already done, without us – fsmoke Apr 20 '23 at 16:10
  • "*The obvious solution*" Can you explain the obvious part? I may have a wrong mental model regarding the difference of the two expressions (none for trivial types like `float`) – MatG Apr 20 '23 at 17:13
  • @MatG: I don't understand. You seem to recognize that there is no difference between the two expressions in this instance, save the fact that one is legal and the other is legal-but-deprecated. So... use the legal one. That's the obvious part. The whole point of deprecating `*=` and its ilk on `volatile` is to make it clear that you know that it isn't a single atomic operation. `f = f * f;` makes that clear in a way that `f *= f;` does not. – Nicol Bolas Apr 20 '23 at 17:15
  • @MatG, difference between operations is: f*=f this operation on lvalue - deprecated, but f=f*f direct assignment - legal by new standard. Reread cppreference more careful in my start post – fsmoke Apr 20 '23 at 17:54