Skip to content

De-duplicate fmt and format functions and optimize #11596

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

Merged
merged 1 commit into from
Mar 25, 2025
Merged

Conversation

ericcurtin
Copy link
Collaborator

@ericcurtin ericcurtin commented Feb 2, 2025

Just use a single function, also only one buffer is required for the operation, no need to copy.

@ericcurtin ericcurtin force-pushed the optimize_fmt branch 2 times, most recently from b0a45a3 to 7435b04 Compare February 2, 2025 15:17
@ericcurtin
Copy link
Collaborator Author

@ngxson PTAL

int size2 = vsnprintf(buf.data(), size + 1, fmt, ap2);
std::string buf;
buf.resize(size);
const int size2 = vsnprintf(const_cast<char *>(buf.data()), buf.size() + 1, fmt, ap2);
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As long as we don't modify past the null terminator (or .size())in the std::string, I think it's fine. At least I've done this kinda thing in various codebases for 10 years and it's never been an issue.

I think:

&buf[0]

is also an option.

But if we don't want to do this it's fine, it just seems sub-optimal to create a vector (which is essentially a poor mans std::string) and then copy all the data to a std::string.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This looks fine for me, but I think the second argument of snprintf should be just buf.size(), without + 1

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tested + 1 is correct, it always null terminates, we will be missing a char if we use buf.size()

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The generated string has a length of at most n-1, leaving space for the additional terminating null character.

it always prints a null character, it will truncate output if you specify too short a value you see, buf.size() is one character too short

Copy link
Member

Choose a reason for hiding this comment

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

The + 1 is fine because the std containers do not explicitly need room for the null terminating character. This is in contrast to plain C string char buf[size] where the string length can be maximum size - 1.

Regarding the UB, I'm also sure that this will always work in the real world, but would still prefer to avoid adding UB to the code (in case this is indeed UB, not sure yet). In this case the performance consideration is not very important, because we use fmt to just print error messages and logs, so it's OK to make the copy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I removed the micro-optimization in case of UB. Makes the review easier for everyone.

Just use a single function, also only one buffer is required for
the operation, no need to copy.

Signed-off-by: Eric Curtin <[email protected]>
@CISC
Copy link
Collaborator

CISC commented Mar 17, 2025

@ericcurtin Has this been forgotten, or not ready to merge?

@ericcurtin
Copy link
Collaborator Author

We can merge if there are no complaints

@CISC CISC merged commit ef19c71 into master Mar 25, 2025
45 of 46 checks passed
@ericcurtin ericcurtin deleted the optimize_fmt branch March 25, 2025 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants