Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -1060,17 +1060,34 @@ template <typename... Args> constexpr auto count_static_named_args() -> int {
}

template <typename Char> struct named_arg_info {
FMT_CONSTEXPR named_arg_info() : name(nullptr), id(0) {}
FMT_CONSTEXPR named_arg_info(const Char* a_name, const int an_id)
: name(a_name), id(an_id) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Initialization is done in init*named_arg, we shouldn't duplicate it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going to try your idea of only calling if the index is greater than zero, but if that doesn't work, I need the default construct and if I have the default construct, GCC10 will need the other one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both functions have been removed. The if check appeased GCC13, it seems.

const Char* name;
int id;
};

template <typename Char>
FMT_CONSTEXPR void check_for_duplicate(
const named_arg_info<Char>* const named_args, const int named_arg_index,
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not overuse const - it just clutters the code without bringing much benefit when the scope is small.

Copy link
Contributor Author

@dinomight dinomight Mar 2, 2025

Choose a reason for hiding this comment

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

I just want my immutable by default like rust 😄 . This is also an area I disagree with the CPP core guidelines. I'll begrudgingly update this, though.

const Char* const arg_name) {
const basic_string_view<Char> arg_name_view(arg_name);
Copy link
Contributor

Choose a reason for hiding this comment

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

You can simplify this by passing arg_name as a string_view.

for (auto i = 0; i < named_arg_index; ++i) {
if (basic_string_view<Char>(named_args[i].name) == arg_name_view) {
report_error("duplicate named args found");
}
}
}

template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
++arg_index;
}

template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
int& named_arg_index, const T& arg) {
check_for_duplicate(named_args, named_arg_index, arg.name);
named_args[named_arg_index++] = {arg.name, arg_index++};
}

Expand All @@ -1084,6 +1101,7 @@ template <typename T, typename Char,
FMT_ENABLE_IF(is_static_named_arg<T>::value)>
FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
int& arg_index, int& named_arg_index) {
check_for_duplicate(named_args, named_arg_index, T::name);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if calling check_for_duplicate only if named_arg_index is nonzero fixes the uninitialized warning.

named_args[named_arg_index++] = {T::name, arg_index++};
}

Expand Down
2 changes: 2 additions & 0 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ TEST(format_test, named_arg) {
EXPECT_THROW_MSG((void)fmt::format(runtime("{a} {}"), fmt::arg("a", 2), 42),
format_error,
"cannot switch from manual to automatic argument indexing");
EXPECT_THROW_MSG((void)fmt::format("{a}", fmt::arg("a", 1),
fmt::arg("a", 10)), format_error, "duplicate named args found");
}

TEST(format_test, auto_arg_index) {
Expand Down
Loading