Don't use static cast for arithmetic conversions (cpp-core-guidelines)

Viewed 936

msvc's code analyzer for the cpp core guidelines tells me

Warning C26472 Don't use a static_cast for arithmetic conversions. Use brace initialization, gsl::narrow_cast or gsl::narrow (type.1).

for this snippet

static_cast<IntType>(static_cast<unsigned long long>(hexValue(digit)) << (digitIdx * 4));

Why shouldn't I use static_cast here?

Also, with brace init this would look like this

IntType{unsigned long long{hexValue(digit)} << (digitIdx * 4)};

which doesn't look any better imo. This looks more like a function style cast than anything else.

I cannot use gsl and I think gsl::narrow is a wrapper around static_cast itself, so is this purely a readability issue here?

2 Answers

so is this purely a readability issue here?

Nope. Brace initialization prohibits narrowing conversions, and will cause a diagnostic. The guideline's purpose is to help protect code from unintended narrowing. A static_cast will allow a narrowing conversion through silently.

You seem to be dealing in integers, so short of using an extended integer type that is larger than unsigned long long, you'll probably not hit any narrowing.

But the guideline is there for the general case, and it's better to write code consistently, even when there is no actual risk.

Here is a link to Microsoft documentation:

https://docs.microsoft.com/en-us/cpp/code-quality/c26472?view=vs-2019

  • gsl::narrow ensures lossless conversion and causes run-time crash if it is not possible.
  • gsl::narrow_cast clearly states that conversion can lose data and it is acceptable.

static_cast doesn't perform these checks, so it is safer to explicitly state your intentions.

Related