Skip to content

static_assert fails in format-inl.h when using FMT_HEADER_ONLY with FMT_USE_LOCALE=0 #4550

Description

@teruyamato0731

Hi,

I'm using {fmt} v12.0.0 with C++20 and have encountered a compilation issue when defining both FMT_HEADER_ONLY and FMT_USE_LOCALE=0.

The Problem

When these two macros are defined simultaneously, the compilation fails with a static_assert error in fmt/format-inl.h:69.

The error seems to be triggered by including <fmt/chrono.h>. It appears that some part of the chrono formatting functionality attempts to get a std::locale, but since FMT_USE_LOCALE=0 is active, fmt::locale is a dummy detail::locale type. This type mismatch causes the static_assert(std::is_same<Locale, locale>::value, ""); to fail.

Compilation Error Log:

In file included from /path/to/project/build/_deps/fmt-src/include/fmt/format.h:4375,
                 from /path/to/project/build/_deps/fmt-src/include/fmt/base.h:2992,
                 from /path/to/project/Core/App/app.cpp:3:
/path/to/project/build/_deps/fmt-src/include/fmt/format-inl.h: In instantiation of 'Locale fmt::v12::locale_ref::get() const [with Locale = std::locale]':
/path/to/project/build/_deps/fmt-src/include/fmt/chrono.h:1598:65:   required from here
/path/to/project/build/_deps/fmt-src/include/fmt/format-inl.h:69:47: error: static assertion failed
   69 |   static_assert(std::is_same<Locale, locale>::value, "");
      |                                               ^~~~~
/path/to/project/build/_deps/fmt-src/include/fmt/format-inl.h:69:47: note: 'std::integral_constant<bool, false>::value' evaluates to false
/path/to/project/build/_deps/fmt-src/include/fmt/format-inl.h:73:10: error: could not convert 'fmt::v12::detail::locale()' from 'fmt::v12::detail::locale' to 'std::locale'
   73 |   return locale();
      |          ^~~~~~~~
      |          |
      |          fmt::v12::detail::locale
make[2]: *** [CMakeFiles/nucleo-g474re.dir/build.make:229: CMakeFiles/nucleo-g474re.dir/Core/App/app.cpp.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:119: CMakeFiles/nucleo-g474re-dokata.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Related ODR Violation Warning

As a related issue, if I do not define FMT_HEADER_ONLY but still define FMT_USE_LOCALE=0 in my application code (while the {fmt} library itself is likely compiled with default settings), I receive ODR (One Definition Rule) violation warnings.

This is because the layout of locale_ref and context changes based on FMT_USE_LOCALE, leading to inconsistencies between translation units.

Warning Log:

/path/to/project/build/_deps/fmt-src/include/fmt/base.h:912:7: warning: type 'struct locale_ref' violates the C++ One Definition Rule [-Wodr]
  912 | class locale_ref {
      |       ^
/path/to/project/build/_deps/fmt-src/include/fmt/base.h:912:7: note: a different type is defined in another translation unit
/path/to/project/build/_deps/fmt-src/include/fmt/base.h:915:15: note: the first difference of corresponding definitions is field 'locale_'
  915 |   const void* locale_;  // A type-erased pointer to std::locale.
      |               ^
/path/to/project/build/_deps/fmt-src/include/fmt/base.h:2668:7: warning: type 'struct context' violates the C++ One Definition Rule [-Wodr]
 2668 | class context {
      |       ^
/path/to/project/build/_deps/fmt-src/include/fmt/base.h:2668:7: note: a different type is defined in another translation unit
/path/to/project/build/_deps/fmt-src/include/fmt/base.h:2672:36: note: the first difference of corresponding definitions is field 'loc_'
 2672 |   FMT_NO_UNIQUE_ADDRESS locale_ref loc_;
      |                                    ^

It seems the combination of FMT_HEADER_ONLY and FMT_USE_LOCALE=0 is not fully compatible, especially when headers like <fmt/chrono.h> are used. Is this an intended limitation, or a bug?

Thank you

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions