Warning in the lastest VS2019

I mentioned this in the Xcode 11.4 thread, but I thought it deserved it’s own thread since it’s an unrelated issue. Github Actions upgraded to VS2019 16.5.0 and now all my ci jobs are failing because I’m getting warnings I can’t figure out.

1>d:\a\cloud\cloud\modules\JUCE\modules\juce_core\containers\juce_ArrayBase.h(155): error C2220: the following warning is treated as an error
1>d:\a\cloud\cloud\modules\JUCE\modules\juce_core\containers\juce_ArrayBase.h(155): warning C4723: potential divide by 0
1>d:\a\cloud\cloud\modules\JUCE\modules\juce_core\containers\juce_ArrayBase.h(155): warning C4723: potential divide by 0
1>d:\a\cloud\cloud\modules\JUCE\modules\juce_core\containers\juce_ArrayBase.h(155): warning C4723: potential divide by 0

The offending line of code looks like this:

return isPositiveAndBelow (index, numUsed) ? elements[index] : ElementType();

No division there. So it must be an issue with the type that is being compiled with the template.

isPositiveAndBelow doesn’t divide either.

template <typename Type>
bool isPositiveAndBelow (int valueToTest, Type upperLimit) noexcept
{
    jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
    return static_cast<unsigned int> (valueToTest) < static_cast<unsigned int> (upperLimit);
}

Any idea what could be causing this or how to figure out what type is causing it?

I’m seeing something similar in juce::Image::getWidth in the UnitTestRunner. As this doesn’t happen in debug mode, my best guess is that the compiler is getting a bit clever with LTCG and inlining this function body somewhere. Once it’s inlined, it spots that the value may be zero, and that it is being used on the RHS of a division. Unfortunately, the error message points us at the non-inlined ‘potential zero’ rather than the place where the division happens. Tracking down the division is the difficult bit…

Yes, as I mentioned in the other thread, I did a test and found that the latest Visual Studio “divide by 0” message happens only in Release mode. In Debug mode it compiles clean, and runs. This is for one of my projects using JUCE develop, and Tracktion Engine develop…

And the error points to line 272 in juce_Image.cpp,

272    int Image::getWidth() const noexcept    { return image == nullptr ? 0 : image->width; }

This happen at link time, so Microsoft must have changed the optimization.

My temporary work-around is to change line 272 as follows;

272    int Image::getWidth() const noexcept    { return image->width; }

…which does at least allow things to compile, link, and run.

I think it’s a compiler bug. They already released 16.5.1

Unfortunately the same issue is present in 16.5.1

Luckily I didn’t update. Still have 16.4.x because we want to release a small Nexus3 update today…

It was with 16.5.1 that I discovered the problem. For me the work-around (I mentioned above) gets me by at the moment. I always compile with “Treat Warnings as Errors” enabled, so I started hitting this immediately after updating to 16.5.1.

Are you able to repro this in any of the example projects from the JUCE repo? I’ve got a potential fix for the issue stemming from juce::Image::getWidth in the UnitTestRunner, but I can’t recreate the ArrayBase issue with the DemoRunner, AudioPluginHost, UnitTestRunner, or Projucer. I’ve also tested some third-party JUCE projects and can’t produce it there either.

I’ve haven’t seen it in the juce code base. But it happens in my open source module Gin that you can get here: https://github.com/figbug/gin

I’ve fixed the issues with Image::getWidth() in the JUCE codebase:

If the ArrayBase issues are triggered when building your code but not JUCE itself, it’s likely that you’re dividing by the result of getValueWithDefault somewhere in your code.

If the ArrayBase issues are triggered when building your code but not JUCE itself, it’s likely that you’re dividing by the result of getValueWithDefault somewhere in your code.

Very likely, but how do I find out where? There must be a better method that guess and check? I use arrays everywhere.

Guess and check is the best I’ve got I’m afraid. I used my IDE to find references to Image::getWidth and then searched for divisions nearby. You could probably do the same with references to Array<NumericType>::operator[].

Yes, I am building clean now on the latest tip. This is with Visual Studio 16.5.1, and with “Treat Warnings as Errors” enabled.

Thank you.

Finally tracked down my warnings. That was far more annoying than it needed to be. Thanks for the suggestions on how to find.