Skip to content

Fairlogger crashes in ROOT Cling with C++23 due to libfmt #66

@YanzhaoW

Description

@YanzhaoW

Hi,

I have been experimenting with running FairLogger with C++23. For now, all the ROOT macro can't work due to libfmt used in FairLogger:

/opt/FairSoft/include/fairlogger/Logger.h:245:69: error: call to consteval function 'fmt::fstring<int>::fstring<9UL>' is not a constant expression
    static std::string startColor(Color color) { return fmt::format("\033[01;{}m", static_cast<int>(color)); }
                                                                    ^
note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
/opt/FairSoft/include/fmt/base.h:2736:54: note: in call to 'basic_string_view(&"\033[01;{}m"[0])'
    if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));
                                                     ^
/opt/FairSoft/include/fairlogger/Logger.h:245:69: note: in call to 'fstring<9UL>("\033[01;{}m")'
    static std::string startColor(Color color) { return fmt::format("\033[01;{}m", static_cast<int>(color)); }
                                                                    ^~~~~~~~~~~~~
/opt/FairSoft/include/fairlogger/Logger.h:247:85: error: call to consteval function 'fmt::fstring<int, const std::basic_string<char, std::char_traits<char>, std::allocator<char> > &>::fstring<15UL>' is not a constant expression
    static std::string ColorOut(Color c, const std::string& s) { return fmt::format("\033[01;{}m{}\033[0m", static_cast<int>(c), s); }
                                                                                    ^
note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
/opt/FairSoft/include/fmt/base.h:2736:54: note: in call to 'basic_string_view(&"\033[01;{}m{}\033[0m"[0])'
    if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));
                                                     ^
/opt/FairSoft/include/fairlogger/Logger.h:247:85: note: in call to 'fstring<15UL>("\033[01;{}m{}\033[0m")'
    static std::string ColorOut(Color c, const std::string& s) { return fmt::format("\033[01;{}m{}\033[0m", static_cast<int>(c), s); }

So basically recent version of libfmt introduces the compile-time check of the parameters when consteval (feature in C++23) is available. This works well with C++ compilers, like gcc or clang. But it doesn't work with Cling interpreter.

I have submitted an issue regarding to this problem in ROOT, see this.

Someone pointed out a partial solution, which is put fmt::runtime around the string when CLing is used. So the change would be like:

static std::string ColorOut(Color c, const std::string& s) {
    #ifdef __CINT__
    return fmt::format(fmt::runtime("\033[01;{}m{}\033[0m"), static_cast<int>(c), s); 
    #else
    return fmt::format("\033[01;{}m{}\033[0m", static_cast<int>(c), s); 
    #endif 
}

whereever fmt::format or fmt::print is used.

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