-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
FMT_COMPILE tests are temporary switched on even if constexpr_if is n… #2061
FMT_COMPILE tests are temporary switched on even if constexpr_if is n… #2061
Conversation
…ot available. Let's on error output
…topping on first fail" Doesn't work anyway( This reverts commit 4be0b40.
…on first fail. Using "fail-fast: false" this time
…t supported is prettified
"include/fmt/compile.h" is ready for review. Other changes will be reverted when all issues with target code will be fixed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thoughts on this PR, maybe they will be useful
# define FMT_COMPILE_IMPL(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string) | ||
#else | ||
namespace fmt_compile_error { | ||
template<class T> struct false_type : std::false_type {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it be done without introducing this additional type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean false_type? It's optional, but error messages of GCC and clang will be a bit uglier, because in case of static_assert, its condition is highlighted. Like following:
static_assert(!std::is_same<T,T>::value, "FMT_COMPILE requires C++17 `constexpr if` compiler support"); return ""; }
| ^~~~~~~~~~~~~~~~~~~~~~~~~
If code in the condition is not obvious then it attends too many unwanted attention. I fear decisions with storing value locally in the named constexpr bool or constant alias don't work on the all supported platforms. Maybe they do. I'm not sure.
template<class T> FMT_CONSTEXPR const char* report_compile_error() {
using false_v = !std::is_same<T,T>::value;
// constexpr bool false_v = !std::is_same<T,T>::value;
static_assert(
false_v, "FMT_COMPILE requires C++17 `constexpr if` compiler support"
);
return "";
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, I added additional namespace fmt_compile_error just not to spoil namespace with the specific code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error is something like:
error: static assertion failed: FMT_COMPILE requires C++17 `constexpr if` compiler support
that can have the expression of course, but the first line has static_assert
string only on most compilers.
template<class T> struct false_type : std::false_type {}; | ||
|
||
template<class T> FMT_CONSTEXPR const char* report_compile_error() { | ||
static_assert( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like broken code-style for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you mean that both scopes are on separate lines, while arguments are indented and are on separate line? It was done by purpose. Because GCC and clang output full line with the failed static_assert's condition. So I think that it's better to place not so interesting parts of this code aside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, code style should be either applied for entire code or disabled with special //clang format off
directive.
Don't think that you as the end user would somehow analyze the code that fail static_assert
since you already have verbose error with static_assert
string.
@@ -44,7 +60,7 @@ struct is_compiled_string : std::is_base_of<compiled_string, S> {}; | |||
std::string s = fmt::format(FMT_COMPILE("{}"), 42); | |||
\endrst | |||
*/ | |||
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string) | |||
#define FMT_COMPILE(s) FMT_COMPILE_IMPL(s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it use the same macro as it used to use before to avoid another macro expansion? Probably not because of docs, but maybe there is a solution for that...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll have an issue with documentation then. I mean if I use
#ifdef __cpp_if_constexpr
# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
#else
# define FMT_COMPILE(s) <error verion>
#endif
But if there is another macro like FMT_CONDITIONAL( __cpp_if_constexpr, FMT_STRING_IMPL(s, fmt::detail::compiled_string), <error verion> )
Then it might work. But FMT_CONDITIONAL will add inderection level too.
Also, the following version might work but is kind of ugly
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
#ifdef __cpp_if_constexpr
#undef FMT_COMPILE
# define FMT_COMPILE(s) <error verion>
#endif
I don't see a problem with extra macro expansion anyway.
Thanks for the PR but the plan is to make |
I mistakenly tried to compile code with FMT_COMPILE without setting c++ standard to c++17 or upper. And as result, I saw a sexy error output that has to be meditated on to figure out what's happened. And it looks like a library bug at the first glance despite it isn't.
The compiler is g++9.3, the standard is c++11 (output of c++14 is the same)
The documentation says that FMT_COMPILE "requires C++17
constexpr if
compiler support", but who reads the documentation? And in my case, I didn't use FMT_COMPILE but received someone else's code instead, so I had no idea what of {fmt} features were used and which are their requirements.I propose to add a better compile-time error explanation. Like the following:
To reproduce it a trivial code is sufficient:
https://godbolt.org/z/T8M88b
I agree that my contributions are licensed under the {fmt} license, and agree to future changes to the licensing.