Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disabling implicit conversion of enum class -> int #1841

Closed
PazerOP opened this issue Aug 29, 2020 · 15 comments
Closed

Disabling implicit conversion of enum class -> int #1841

PazerOP opened this issue Aug 29, 2020 · 15 comments

Comments

@PazerOP
Copy link

PazerOP commented Aug 29, 2020

It seems this feature was added based on #391 and #984, but I personally consider this a bug: the entire purpose of enum class is to prevent any kind of implicit casting. If I wanted to format it as an integer, I should be forced to cast it to an integer or create my own formatter. Is there any recommended way to disable this? Perhaps a preprocessor option?

I have a custom formatter for some specific enum classes, but this implicit casting prevents me from being able to safely forward declare any of my enum classes, since if the custom formatter doesn't get included, format falls back to the default enum class -> int conversion. My formatter uses unique formatting specifiers that don't match anything found with the default int formatter, so when the wrong formatter is used a format_error is thrown.

@foonathan
Copy link
Contributor

You can also forward declare the formatter specialization, then trying to format then is a compile error.

@vitaut
Copy link
Contributor

vitaut commented Aug 29, 2020

There is no way to disable formatting of enums other than what Jonathan suggested.

@vitaut vitaut closed this as completed Aug 29, 2020
@PazerOP
Copy link
Author

PazerOP commented Aug 29, 2020

Unfortunately that suggestion doesn't fix the problem, since it's still "dangerous by default". Is there any chance that an option might be added like I suggested?

Would you happen to know if this implicit casting behavior is part of std::format? I looked through the proposals I could find, but couldn't find any mention of enum class formatting behavior.

@vitaut
Copy link
Contributor

vitaut commented Aug 30, 2020

Is there any chance that an option might be added like I suggested?

I don't think it's worth adding yet another configuration option. You could use compile-time format string checks to diagnose this earlier or make your format specs compatible with standard ones if possible.

Would you happen to know if this implicit casting behavior is part of std::format?

I don't recall from the top of my head - please check the current specs at https://eel.is/c++draft/format.

@strasdat
Copy link

strasdat commented Jul 26, 2021

It seems like that fmt now ignores ostream overloads for enum classes. @vitaut, is this intended behavior? Are there any recommended workarounds?

Edit: Never-mind and apologies for the noise. The overload still works and seems to take precedence over the to int conversion.

@vitaut
Copy link
Contributor

vitaut commented Jul 26, 2021

I recommend providing a formatter specialization.

@ropieur
Copy link

ropieur commented Nov 18, 2021

To me, the implicit conversion is just a bug. It goes against the enum class policy. In C++23, std::to_underlying will be introduced for this purpose. If someone wants to display an enum class as an integer it should convert it explicitly or provide a formatter specialization. Without them, this should result in a compiler error.

@ropieur
Copy link

ropieur commented Nov 22, 2021

https://eel.is/c++draft/format is silent about enum class'es. And the examples I found on the web show that an enum class is considered as a user-defined type and requires a formatter.

@PazerOP
Copy link
Author

PazerOP commented Nov 22, 2021

Fwiw, my eventual solution was to replace all calls to fmt functions with my own format/print function that checks for enum classes at compile time. Obviously this is not really reasonable for any kind of established project.

@vitaut
Copy link
Contributor

vitaut commented Nov 22, 2021

@PazerOP, could you provide an example illustrating the specific problem you had with enum classes? (preferably a godbolt link)

@vitaut
Copy link
Contributor

vitaut commented Nov 25, 2021

Anyway, thinking more of it, the fact that there is no implicit conversion from scoped enums to integers does suggest that they shouldn't be formatted as integers by default, so reopening.

@vitaut vitaut reopened this Nov 25, 2021
@vitaut
Copy link
Contributor

vitaut commented Nov 25, 2021

Also reported in #1424.

@vitaut
Copy link
Contributor

vitaut commented Dec 9, 2021

The regression has been fixed in fd62fba (tracked in #1424). Thanks for reporting.

@ropieur
Copy link

ropieur commented Dec 18, 2021

@vitaut , by when will you produce an official release including this fix?

@vitaut
Copy link
Contributor

vitaut commented Dec 18, 2021

I don't have a specific release date yet.

ns-codereview pushed a commit to couchbase/kv_engine that referenced this issue Apr 20, 2022
Upgrading to fmtlib 8.1.1 removed support for implicitly converting
strongly-typed enums (enum class) to int when printing via fmtlib -
see fmtlib/fmt#1841

This is considered a bug by fmtlib, as strongly-typed enums should be
treated as such - to print them either provide a formatter, or cast to
their underlying type.

This highlighted that we had missed a number of operator<< overloads
for custom enum classes - and one instance where our operator<< was
not used as we were missing an include of <fmt/ostream.h>

Change-Id: If0f4e19f3eff4ebf4b4e3ccec1f0815c794a709b
Reviewed-on: https://review.couchbase.org/c/kv_engine/+/173823
Tested-by: Build Bot <[email protected]>
Reviewed-by: Trond Norbye <[email protected]>
nyh added a commit to nyh/scylla that referenced this issue Jun 26, 2022
Starting with version 8.1 of fmt, one can no longer print an enum
class and assume automatic conversion to the integer underlying type.
See fmtlib/fmt#1841 for this change.

In this patch we fix the one place where we assumed this implicit
conversion works, and make the conversion explicit.

Fixes scylladb#10884

Signed-off-by: Nadav Har'El <[email protected]>
wentasah added a commit to wentasah/boardproxy that referenced this issue Jul 25, 2022
The error is:

    .../include/fmt/core.h:1728:7: error: static assertion failed:
    Cannot format an argument. To make type T formattable provide a
    formatter<T> specialization: https://fmt.dev/latest/api.html#udt

fmt 8.0.1 worked well. This is probably related to
fmtlib/fmt#1841.
geissonator pushed a commit to openbmc/openpower-occ-control that referenced this issue Nov 9, 2022
fmtlib removed support for automatically formatting enums as integers
in version 9. See fmtlib/fmt#1841.

Signed-off-by: Eddie James <[email protected]>
Change-Id: I6a5d04187e55c94d39d8b5ee334f9a37c93081ce
davidmoreno added a commit to davidmoreno/rtpmidid that referenced this issue Sep 24, 2023
Newer fmt disabled automatic formatting of enums, see
fmtlib/fmt#1841
davidmoreno added a commit to davidmoreno/rtpmidid that referenced this issue Sep 24, 2023
Newer fmt disabled automatic formatting of enums, see
fmtlib/fmt#1841
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants