Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Use snprintf instead of sprintf (even in trivial case)#1236

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
eddelbuettel merged 1 commit intomasterfromfeature/no_sprintf
Oct 27, 2022

Conversation

@eddelbuettel
Copy link
Member

This commit replace the sole usesprintf withsnprintf. A full run of reverse depends checks revealed no 'change to worse'.

Checklist

  • Code compiles correctly
  • R CMD check still passes all tests
  • Prefereably, new tests were added which fail without the change
  • Document the changes by file inChangeLog

@kevinushey
Copy link
Contributor

snprintf() always writes a null terminator as well, so I think you can safely pass the full buffer size when calling it (no -1).

inlineconstchar* coerce_to_string<RAWSXP >(Rbyte from){
staticchar buff[3];
::sprintf(buff,"%02x", from);
snprintf(buff,2,"%02x", from);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have a unit test for this one? I'm worried we might be truncating the representation here.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I would welcome one. Can you think of one?

I did run it over nearly 2600 CRAN packages though as the usual reverse depends check...

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll try to put one together later this morning.

eddelbuettel reacted with heart emoji
@kevinushey
Copy link
Contributor

Here's an example showcasing the issue:

#include <Rcpp.h>using namespace Rcpp;// [[Rcpp::export]]std::string test() {    return Rcpp::internal::coerce_to_string<RAWSXP>(0xaa);}/*** Rtest()*/

Running with this PR, you'll see:

> test()[1] "a"

Given that this change doesn't cause any failures I guess this isn't a commonly-exercised code path.

@eddelbuettel
Copy link
MemberAuthor

Whoops. Scrambled egg on my face.

@kevinusheykevinushey mentioned this pull requestOct 27, 2022
4 tasks
@eddelbuettel
Copy link
MemberAuthor

eddelbuettel commentedOct 27, 2022
edited
Loading

snprintf() always writes a null terminator as well, so I think you can safely pass the full buffer size when calling it (no -1).

I was a little fuzzy / unaware on this one butdo recall seeingmany use of -1 in the wild. Including in the same source file a few lines above:

staticchar tmp[128];
snprintf(tmp,127,"%f", x);

but then not here (so I changed it in the PR -- the link shown is from the master branch)

staticchar buffer[NB] ;
snprintf( buffer, NB,"%*d",integer_width(from), from );

What is a good rule about when 'n == n' is safe and when it is not?

@eddelbuettel
Copy link
MemberAuthor

Rebased and updated. Let me know what you think@kevinushey

@kevinushey
Copy link
Contributor

What is a good rule about when 'n == n' is safe and when it is not?

Good question... it's complicated and comes down to whether the format / print routine writes a null terminator for you or not. Sincesnprintf() always writes a null terminator, it's safe to usen == n where the buffer includes space for the null terminator, but for other formatting functions the documentation needs to be checked to be sure.

Another wrinkle forsnprintf() is that, if you're using it to figure out the buffer size when printing, you need to be careful. Fromhttps://en.cppreference.com/w/cpp/io/c/fprintf:

  1. Writes the results to a character string buffer. At most buf_size - 1 characters are written. The resulting character string will be terminated with a null character, unless buf_size is zero. If buf_size is zero, nothing is written and buffer may be a null pointer, however the return value (number of bytes that would be written not including the null terminator) is still calculated and returned.

So you might write code like:

// figure out size of formatted string// NOTE: does _not_ include null terminator!int n = snprintf(nullptr, 0, "%s\n", "code");// create a buffer, adding 1 for the null terminatorstd::vector<char> buffer(n + 1);// format string into buffer, again adding 1 for terminatorsnprintf(&buffer[0], n + 1, "%s\n", "code");

tl;dr: it's unfortunately complicated and depends on whether the formatter writes a null terminator for you, and in what conditions it writes the null terminator.

eddelbuettel reacted with thumbs up emoji

@kevinushey
Copy link
Contributor

This is also why I am so happy to havefmt.

eddelbuettel reacted with laugh emoji

Copy link
Contributor

@kevinusheykevinushey left a comment

Choose a reason for hiding this comment

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

LGTM!

@eddelbuettel
Copy link
MemberAuthor

Thanks for the comment above. Reading it I realize I once knew only n-1 may be copied to leave room. So yes, 'it depends'.

Anyway, we made a nice improvement and you rightly took me to school as there shouldn't be a PR without a test under it. All good.

@eddelbuetteleddelbuettel merged commitc05fd1b intomasterOct 27, 2022
@eddelbuetteleddelbuettel deleted the feature/no_sprintf branchOctober 27, 2022 17:30
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@kevinusheykevinusheykevinushey approved these changes

@Enchufa2Enchufa2Awaiting requested review from Enchufa2

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

3 participants

@eddelbuettel@kevinushey

[8]ページ先頭

©2009-2025 Movatter.jp