make std::optional constructor emit implicit conversion warnings
Asked Answered
L

1

11

I'm trying to rid my codebase of lossy implicit conversions, so I'm compiling with the -Wconversion flag under clang++. The following code is expected to output a warning, but does not.

#include <cstddef>
#include <iostream>
#include <limits>
#include <optional>


int main() {
  size_t x = std::numeric_limits<size_t>::max();
  std::cout << x << std::endl;

  auto x2 = std::make_optional<uint8_t>(x);
  std::cout << (int)*x2 << std::endl;

  return 0;
}

On the make_optional line, my size_t is silently narrowed to a uint8_t. If instead I write uint8_t x2 = x; for example, I get the expected narrowing conversion warning.

This also happens when I use the std::optional constructor. In the code I gave, make_optional overload 2 is called which calls optional constructor overload 6. This constructs the optional as if direct-initializing the contained value, and direct initialization does not raise an implicit narrowing conversion warning.

Other than writing an optional class of my own that does not hide narrowing conversions, is there any way to cause the above code to raise a narrowing conversion warning?

Leonoreleonsis answered 11/4, 2019 at 19:40 Comment(4)
I was about to say "use clang-tidy", but apparently there is no check covering that. Even in build from today's master, 9.0.0svn. Maybe other static-analyzer can detect such case.Pirog
make_optional is sensed to use deduction... else directly use optional<T>.Sirloin
Maybe file it against libstdc++, I am not exactly sure why that doesn't generate a warning, as making a similar constructor myself did. Interestingly I also got a warning in all cases with MSVC (C4244 or C4267 for size_t).Dextroamphetamine
No compiler to hand, but doesn’t optional<uint8_t>{x} fail as desired?Matrona
F
1

List initialization prohibits narrowing conversions.

By the way, it looks like some compilers do warn on the issue: https://godbolt.org/z/P8Mv8v83d

Foreshow answered 19/11, 2021 at 0:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.