Error: non-const expression can't be narrowed from type 'int' to 'float'

When defining nebRec as:

Rectangle nebRec{0.0, 0.0, nebula.width/8, nebula.height/8};

I get the error - non-constant-expression cannot be narrowed from type ‘int’ to ‘float’ in initializer list [-Wc++11-narrowing]

If I define nebRec the same way scarfyRed is defined it works fine.

Why is this?

2 Likes

This is a warning not a error in such.

Basically it warning that you potentially lose data with nebula.width/8 because the nebula.width variable is a interger type and when divided by 8 the result has potential to be a float type value. i.e. 241 / 8 = 30.125 there the nebula.width will only store 30 and drop the fraction.

Now why it only does this when you initialise variable for nebRec within {} (this initialiser list) is because the complier will check for this type narrowing from into to float with in a initialiser list.

But it will not check it if you initialise a variable like this.
nebRec.width = nebula.width/8;

Weird since you potentially have the same problem.

Narrowing conversions

list-initialization limits the allowed implicit conversions by prohibiting the following:

  • conversion from a floating-point type to an integer type

  • conversion from a long double to double or to float and conversion from double to float, except where the source is a constant expression and overflow does not occur

  • conversion from an integer type to a floating-point type, except where the source is a constant expression whose value can be stored exactly in the target type

  • conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type

  • conversion from a pointer type or pointer-to-member type to bool (since C++20)

Note that it doesn’t prohibit intfloat. Clang does apparently reject it though

Compiler Explorer

Not sure if that’s a bug or that’s only a minimum spec and implementations can reject more narrowing conversions than that I misread, that is the list of what the standard considers narrowing.

@DanM @JacquesVB Rectangle has all 4 elements be of float type. Because nebula.width/8 is a non-constant expression with integer type result, the warning kicks in (the third case in DaniM’s bulleted list).

I suspect that nebula.width/8.0 and nebula.height/8.0 might pass muster though.

@leondhay There are some assigning int to float warnings possible. I think the problem is that such assignment operations are assumed to be intended as “narrowings.” The problem is with / between int values being an int-valued operation. Any damage is already done right there. Dividing by 8.0 instead of 8 will cure that if a more-precise 1float` value is intended.

@orcmid My bad, I didn’t see that Rectangle has 4 elements of float type. I wonder if there is way to “explicitl conversion” method so that expression will result in float value . Because even if I do the following within list-initialization I still get the warnings on the expressions

Rectangle nebRec{0.0, 0.0, nebula.width/8.0, nebula.height/8.0};

I read a bit about static-cast conversion and just tried the above with it.

Rectangle nebRec{0.0, 0.0,static_cast<float>(nebula.width/8.0),static_cast<float>(nebula.height/8.0)};

That worked, no more warnings. Thanks @DanM and @orcmid.

2 Likes

Explicit conversion solved the issue. Thanks to everyone who responded to this post!

1 Like

Does explicit casting of the entire expression result in lost data vs casting of the expression’s operands?

If (width/8) results in an integer, casting that integer to a float will satisfy the compiler but will it have already done the “narrowing” conversion by then?

Yes. Though if you cast one of them to a float then you will do a floating point division and end up with a float

Compiler Explorer

And you can see the implicit conversions happening with cppinsights

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.

Privacy & Terms