by grep_it on 7/30/21, 8:06 PM with 150 comments
by TazeTSchnitzel on 7/30/21, 9:40 PM
• It takes a buffer size and truncates the output to the buffer size if it's too large.
• The buffer size includes the null terminator, so the simplest pattern of snprintf(buf, sizeof(buf), …) is correct.
• It always null-terminates the output for you, even if truncated.
• By providing NULL as the buffer argument, it will tell you the buffer size you need if you want to dynamically allocate.
And of course, it can safely copy strings:
snprintf(dst_buf, sizeof(dst_buf), "%s", src_str);
Including non-null-terminated ones: snprintf(dst_buf, sizeof(dst_buf), "%.*s", (int)src_str_len, src_str_data);
And it's standard and portable, unlike e.g. strlcpy. It's one of the best C99 additions.by jonathrg on 7/30/21, 9:05 PM
by barosl on 7/30/21, 8:55 PM
by jabl on 7/30/21, 9:11 PM
by corndoge on 7/30/21, 9:04 PM
by legulere on 7/30/21, 9:07 PM
by andrewmcwatters on 7/30/21, 9:19 PM
by csnover on 7/30/21, 9:03 PM
by howtofly on 7/31/21, 5:00 AM
In our team c-string is prefixed with sz_, e.g. char sz_name[13], and we always use a safe subset(or a safe replacement) of strxxx functions with these sz_ prefixed variables. Using memxxx with sz_ variables is explicitly forbidden, since it may break the NULL-terminating contract.
The sz_ prefix convention is by no ways like the hungarian naming nonsense. Suppose that you have "char sz_name[13]" in a structure of configuration parameters, sz_ tells the guy changing the field to keep it NULL-terminated, if they don't, it's their fault. On the other side, users of this field can safely use printf("%s", sz_name) without the risk of crashing the program.
For safe replacements of strcpy, I recommend: https://news.ycombinator.com/item?id=27537900
by aidenn0 on 7/31/21, 2:59 AM
OpenWatcom, which implements a late draft of the standard behaves as expected on their testcase:
Runtime-constraint violation: strcpy_s, s1max > RSIZE_MAX.
ABNORMAL TERMINATION
The reason not to use the _s versions isn't that they are bad, it's that basically nobody has implemented them (hence me having to use Open Watcom to demonstrate this example)[edit]
Just noticed that in the page they linked to at the top when they mention strcpy_s, it notes that the MSVC implementation predates even the original draft of the standard and lacks RSIZE_MAX.
by b33j0r on 7/30/21, 9:10 PM
(Rust crowd snickers as they unwrap<‘jk> &mut *foo_buf)
by ncmncm on 7/31/21, 2:58 AM
strlcpy.
Every use of it I have seen was subtly incorrect. To use it correctly takes more code than anybody wants to write, or (AFAICT) ever does.
strcat is worse than both, though.
by matheusmoreira on 7/31/21, 4:17 AM
I don't even know why the str* functions exist. They're just worse versions of mem* functions.
by Animats on 7/31/21, 1:23 AM
by einpoklum on 7/30/21, 9:01 PM
by forrestthewoods on 7/30/21, 9:26 PM
I think it’s a travesty that these languages defined an API but didn’t provide an implementation. Hindsight is 20/20, but what a nightmare!
It is far more rational to provide an implementation using standard language features. It’s not like strcpy needs to make a syscall!