Anyway to get rid of these VS2019 warnings C4244 for 'ValueType' (Templates)?

Warning	C4244	'argument': conversion from 'float' to 'ValueType', possible loss of data

I’m getting a bunch of these warnings in my code, and I’m wondering if there is anyway to deal with them other than a #pragma disabled.

This seems to happen everywhere a Template function (I think that’s what they’re called?) that can accept different value types is used. Here’s an example (pseudo-code) that causes this warning:

float globalScalingFactor = 1.5;
auto componentHeight = 25.0f * globalScalingFactor;
auto componentWidth = 100.0f * globalScalingFactor;
auto marginX = 4.0f * globalScalingFactor;
auto marginY =  4.0f * globalScalingFactor;

textButton.setBounds (area.removeFromTop (componentHeight).removeFromRight (componentWidth).reduced (marginX, marginY));

Each of the uses of the float variables in the removeFromTop(), removeFromRight() etc. calls produce a warning: conversion from ‘float’ to ‘ValueType’.

I’m using floats for my GUI dimensions and distances, and I have 100’s of these type of calls/errors in my resized() functions, and I wonder if there’s a simple way to cast this such that the warnings don’t happen - although it would be a pain to have to cast every single use of the variables…

I know I can hide all of these with #pragma warning(disable : 4244), but I’d like to be able to see “real ones” that might be more important.

What exactly is area in your example? If it’s a Rectangle<int> then you should pass ints to its functions.
If you want to work with floats only, then you’ll need to make area of type Rectangle<float>.
As long as you keep mixing float and int, you will frequently get compiler warnings.
BTW, there is a similar clang warning flag that you can use on macOS. If I remember well, it’s -Wfloat-conversion.

I hope this helps!

1 Like

do the right thing, aka cast from float to int. either up front when you do the calculations, or in the setBounds() call. Personally, I do all the math in floats, and then cast to int when needed (ie. setBounds().

Sorry, I should have put that in the code example. It’s:

auto area = getLocalBounds();

So it’s a Rectangle<int>. I didn’t even think of that. Is there a way to cast the result of getLocalBounds to a Rectangle<float> ? The few things I tried didn’t work…

Like this, you mean?:

textButton..setBounds (area.removeFromTop ((int) componentHeight).removeFromRight ((int) midiAreaWidth).reduced ((int) marginX, (int) marginY));

That’s a ton of casting for 100’s of these statements…

auto area = getLocalBounds().toFloat();

1 Like

Doh! Thank you. Will see if that gets me anywhere.

So I tried a Rectangle<float>, like example code:

Rectangle<float> area = getLocalBounds().toFloat();

float globalScalingFactor = 1.5f;
auto componentHeight = 25.0f * globalScalingFactor;
auto componentWidth = 100.0f * globalScalingFactor;
auto marginX = 4.0f * globalScalingFactor;
auto marginY =  4.0f * globalScalingFactor;

textButton.setBounds (area.removeFromTop (componentHeight).removeFromRight (componentWidth).reduced (marginX, marginY));

And now, instead of warnings, I get actual errors:

error C2664: 'void juce::Component::setBounds(juce::Rectangle<int>)': cannot convert argument 1 from 'juce::Rectangle<float>' to 'juce::Rectangle<int>'

setBounds() takes a ValueType, so it seems you should just be able to pass in a Rectangle<float> - so what am I doing wrong? Thanks!

You can use getSmallestIntegerContainer, toNearestInt, or toNearestIntEdges, depending on the behavior you want, to convert a Rectangle<float> into a Rectangle<int>.

Thanks, but I don’t want to convert a Rectangle<float> into a Rectangle<int> - I started this thread with a Rectangle<int>. I’m just trying a Rectangle<float> (now) to see if it solves my other issue. I’d like to know at this point, why setBounds() won’t accept a Rectangle<float> when it uses a ValueType for arguments…

setBounds takes a Rectangle<int> (https://docs.juce.com/master/classComponent.html#a1bd97a58b5ab72b3e803c6b90a41ea4f). It can’t take anything else.

Rectangle<float> is a different class. There is no implicit conversion between Rectangle<int> and Rectangle<float>.

yes, setBounds only takes an int Rectangle, which is why I said I do the casting in my code. I want to preserve accuracy, so I do all position and size calculations in float, and then cast when needed in the setBounds call. I don’t use a float Rectangle with toInt conversion, because I still run into the same issue, as some of my values may be int not float. Anyways, the reason you have 100’s of casts to catch up on, is because you weren’t casting as you wrote the code (or at least when the warning came up when compiling). Bite the bullet and do the casting update, then just keep your compiles free of warnings as you work. Rarely do you want to disable a warning with a pragma, most of the time you should do the right thing to fix the warning.

1 Like

I see. I was looking at Rectangle::setBounds(), not Component::setBounds(). Thanks.

Well, I started working on Mac, where there are no warnings for this kind of thing. Xcode doesn’t care. It’s only when I added Windows to the mix that I noticed this issue. Now I have a zillion of these.

I hear you there. I guess I’ll just have to cast every single variable in my calls to setBounds(). I like the idea of keeping the GUI calculations in the float realm.

There are warnings: -Wfloat-conversion, -Wconversion, etc. But Projucer doesn’t enable them by default.

That’s a flaw in Projucer. It doesn’t use consistent warning levels on all platforms.

The JUCE team tried to correct this by adding a new setting in Projucer 5.4.4 called “Add Recommended Compiler Warning Flags” (you can find that setting in each configuration).

On macOS, this adds the following warning flags:

If you want to get similar warning levels on macOS and Windows, you should enable that setting.

I hope this helps!

2 Likes

Thanks - that’s useful information!