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

Always use FMT_STRING internally where possible [Issue #2002] #2006

Merged
merged 13 commits into from
Nov 15, 2020

Conversation

yeswalrus
Copy link
Contributor

Update a few internal calls to fmt::format to use FMT_STRING, improving compatibility with the FMT_ENFORCE_COMPILE_STRING compile option.

I agree that my contributions are licensed under the {fmt} license, and agree to future changes to the licensing.

@yeswalrus yeswalrus changed the title Always use FMT_STRING internally where possible [#2002] Always use FMT_STRING internally where possible [Issue #2002] Nov 11, 2020
const Args&... args) {
Args&&... args) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks unrelated, please revert.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, though this was done since I noticed it would bring the function more into alignment with the other examples of and documentation for functions using make_args_checked

@yeswalrus yeswalrus requested a review from vitaut November 12, 2020 22:24
@yeswalrus yeswalrus force-pushed the fix-forced-compile-checks branch from d4742be to 969dcce Compare November 12, 2020 22:26
Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Looks good in general but please address the inline comment.

Comment on lines 769 to 773
const Char pr_f[] = {'{', ':', '.', '{', '}', 'f', '}', 0};
if (precision >= 0) return format_to(out, pr_f, val, precision);
if (precision >= 0) {
return vformat_to(out, to_string_view(pr_f),
make_format_args<context>(val, precision));
}
Copy link
Contributor

@vitaut vitaut Nov 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make pr_f static constexpr and keep format_to (don't change it to vformat_to). static constexpr strings should work with FMT_STRING:

static constexpr const Char pr_f[] = {'{', ':', '.', '{', '}', 'f', '}', 0};
  if (precision >= 0) return format_to(out, FMT_STRING(pr_f), val, precision);

Same below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, good to know! Won't that break on platforms where FMT_CONSTEXPR_DECL evaluates to noop though?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On that platform FMT_STRING should also evaluate to noop (at least in theory).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This apparently breaks on windows, even after correcting it to use SFINAE to avoid compiling the {:.{}f} format string with an integral type. I'm adding a test for using FMT_STRING with a static FMT_CONSTEXPR_DECL, and I'll see if I can get a workaround

@yeswalrus yeswalrus requested a review from vitaut November 13, 2020 19:41
@yeswalrus yeswalrus force-pushed the fix-forced-compile-checks branch from af0ede3 to 03c29de Compare November 14, 2020 00:17
@yeswalrus
Copy link
Contributor Author

yeswalrus commented Nov 14, 2020

I know you asked me not to modifiy tests, but I've added a demonstration of a failure to format-test.cc starting at line 1819, and filed a bug report against MSVC++ here: https://developercommunity.visualstudio.com/content/problem/1256077/internal-compiler-failure-with-macro-defining-lamb.html
I've modified chrono.h to use enable_if in a sadly combinatoric way to avoid having to use FMT_STRING on a constexpr char array and to avoid compiling a compile-time checked format string with a bad type. LMK if you are aware of a better solution for this.

@yeswalrus yeswalrus force-pushed the fix-forced-compile-checks branch from 07f3550 to fc3832f Compare November 14, 2020 02:21
@yeswalrus
Copy link
Contributor Author

I've simplified by directly calling the underlying function, detail::compile_string_to_view, to work around the MSVC crash. It simplifies things significantly, so LMK which version you'd prefer.

Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good but please address inline comments.

return format_to(out, std::is_floating_point<Rep>::value ? fp_f : format,
val);
static FMT_CONSTEXPR_DECL const Char pr_f[] = {'{', ':', '.', '{', '}', 'f', '}', 0};
if (precision >= 0) return format_to(out, compile_string_to_view(pr_f), val, precision);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please apply clang-format to your changes.

Comment on lines +1820 to +1829
(void)static_with_null;
(void)static_with_null_wide;
(void)static_no_null;
(void)static_no_null_wide;
#if !defined(_MSC_VER)
EXPECT_EQ("42", fmt::format(FMT_STRING(static_with_null), 42));
EXPECT_EQ(L"42", fmt::format(FMT_STRING(static_with_null_wide), 42));
EXPECT_EQ("42", fmt::format(FMT_STRING(static_no_null), 42));
EXPECT_EQ(L"42", fmt::format(FMT_STRING(static_no_null_wide), 42));
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this because we already test this below.

Copy link
Contributor Author

@yeswalrus yeswalrus Nov 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite - you test with constexpr locals, which are a c++ 17(14?) feature, but static constexpr char arrays are valid all the way back to c++11 and this exposes a bug in MSVC.

@yeswalrus yeswalrus requested a review from vitaut November 14, 2020 22:08
@vitaut vitaut merged commit befd7d4 into fmtlib:master Nov 15, 2020
@vitaut
Copy link
Contributor

vitaut commented Nov 15, 2020

Thank you!

@yeswalrus yeswalrus deleted the fix-forced-compile-checks branch November 15, 2020 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants