1

I'm a .NET developer trying to do c++ (ahem) and I encountered a compiler warning in here:

const auto u = (textel.character % font_glyph_column_count) * font_glyph_size; // <- all int
const auto v = (textel.character / font_glyph_column_count) * font_glyph_size; // <- all int
const auto top_left_uv = sf::Vector2f(u, v);

In the last line, where 'u' and 'v' are passed as args to the Vector ctor, the compiler says:

conversion from 'const int' to 'T', possible loss of data

Ok, .NET doesn't do this, but i looked it up and i understand that not all int32 can be represented by a float. (Now I wonder why .NET doesn't warn about this :) )

So, my .NET inspired solution is - apparently called - a "C cast", which my Resharper complains about: so, i change it to a static_cast. Okido...

const auto u = static_cast<float>(textel.character % font_glyph_column_count) * font_glyph_size;
const auto v = static_cast<float>(textel.character / font_glyph_column_count) * font_glyph_size;
const auto top_left_uv = sf::Vector2f(u, v);

But yuk! now my arithmetic code gets littered with these casts, while the juggling around of integer computation is very deliberate, and having to put the result in float-based vectors, is also necessary...

I could change eg. font_glyph_size to a float, so casting becomes implicit, but it makes more sense for it to be a discrete amount of pixels, so int...

Can this code be made prettier?

Thomas
  • 432
  • 3
  • 13
  • Depending on how you define 'elegant', you may like to use the [Functional-Style Cast](https://stackoverflow.com/q/4474933/10871073) - where you can do, say, `float f = float(i)`. – Adrian Mole May 30 '20 at 07:47
  • 1
    Why not manually specify the types of `u` and `v`? AFAICT you're not actually using any fractional math (if `font_glyph_size` is integral), so the cast doesn't have to be placed within the `*`. Also, `const auto var = constructor(args)` is needlessly verbose: variable declarations of class type are constructor calls. Write `const sf::Vector2f top_left_uv(u, v);` (or, as I'd prefer, `sf::Vector2f const top_left_uv(u, v);`). – HTNW May 30 '20 at 07:48
  • @AdrianMole i found the functional style, i find it more elegant. But a lot of people say it's like c casts, better not use it... So, I was wondering what else was possible. – Thomas May 30 '20 at 08:47
  • @HTNW You are right, everything is int in that calculation, but when I do const float u = ..., the warning is gone, but clang-tidy still complains about the narrowing conversion. And the ctor: thanks, I still have to get used to these more compact initializations of C++, it's cleaner indeed. – Thomas May 30 '20 at 08:50
  • You are trying to convert a value from one type to another type. This is inherently a dangerous operation, and having a verbose syntax like `static_cast` *is* an elegant way of doing that when you absolutely have to. – cigien May 30 '20 at 16:28
  • @cigien Yes, i'm starting to see it that way too :) – Thomas May 31 '20 at 07:16

1 Answers1

0

You can use c stryle cast.

int a = 1; float b = (float) a;

Also you can do just

int a = 1; float b = a;

Orest
  • 43
  • 1
  • 7
  • My question is about finding a modern solution. c style cast are disadvised everywhere. Your second suggestion gives the same narrowing conversion warning as my code, which is what I'm trying to solve. – Thomas May 30 '20 at 09:08