Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.arch.embedded > #28423
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Newsgroups | comp.arch.embedded |
| Subject | Re: snprintf return value |
| Date | 2018-12-10 13:15 +0100 |
| Organization | A noiseless patient Spider |
| Message-ID | <pulldd$sl3$1@dont-email.me> (permalink) |
| References | <pulekl$n55$1@dont-email.me> |
On 10/12/18 11:20, pozz wrote:
> I usually have a static buffer and I don't want to use a dynamic buffer.
>
> char buf[BUFLEN];
>
> I have to construct a long string, and it is quite easy to call snprintf
> multiple times:
>
> int n = 0;
> n += snprintf(&buf[n], BUFLEN - n, ...);
> n += snprintf(&buf[n], BUFLEN - n, ...);
> n += snprintf(&buf[n], BUFLEN - n, ...);
> n += snprintf(&buf[n], BUFLEN - n, ...);
>
> I was convinced the return value was the real number of characters
> written in buf, not counting final '\0'. In this case, the above code
> works.
>
> I just noticed the return value of snprintf() is the number of
> characters of the generated string as if the buffer was long enough. So
> the above code doesn't work.
>
> The return value of snprintf() is useful if you want to dynamically
> reallocate the buffer so it can store all the string. In my case I would
> prefer to truncate the string at the end of the static buffer. The above
> code should be redesigned as:
>
> int n = 0;
> n += snprintf(&buf[n], BUFLEN - n, ...);
> if (n >= BUFLEN - n) return;
> n += snprintf(&buf[n], BUFLEN - n, ...);
> if (n >= BUFLEN - n) return;
> n += snprintf(&buf[n], BUFLEN - n, ...);
> if (n >= BUFLEN - n) return;
> n += snprintf(&buf[n], BUFLEN - n, ...);
> if (n >= BUFLEN - n) return;
>
> The code starts being not readable. I'm thinking to create a new
> snprintf2():
>
> int
> snprintf2(char *str, size_t size, const char *format, ...) {
> va_list args;
>
> va_start(args, format);
> int n = vsnprintf(str, size, format, args);
> va_end(args);
> return (n >= size) ? (size - 1) : n;
> }
This is going to add a good extra layer of inefficiency, stop
optimisations that your compiler could do (such as converting some cases
to strcat), and stop the format checking provided by gcc unless you
manually add the right attributes.
I'd be tempted to put things in a macro here:
#define snprintf2(str, size, format...) \
({ int n = snprintf(str, size, ## format); \
(n >= size) ? (size - 1) : n })
Yes, it's a gcc extension - but the point is to get the gcc features of
warnings and optimisation. If you are not using gcc, then I guess your
function is okay.
Back to comp.arch.embedded | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
snprintf return value pozz <pozzugno@gmail.com> - 2018-12-10 11:20 +0100
Re: snprintf return value Reinhardt Behm <rbehm@hushmail.com> - 2018-12-10 18:24 +0800
Re: snprintf return value pozz <pozzugno@gmail.com> - 2018-12-10 11:32 +0100
Re: snprintf return value Philipp Klaus Krause <pkk@spth.de> - 2019-01-01 12:59 +0100
Re: snprintf return value David Brown <david.brown@hesbynett.no> - 2018-12-10 13:15 +0100
Re: snprintf return value Clifford Heath <no.spam@please.net> - 2018-12-11 08:49 +1100
Re: snprintf return value Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> - 2018-12-11 11:41 -0500
Re: snprintf return value Clifford Heath <no.spam@please.net> - 2018-12-12 10:34 +1100
Re: snprintf return value David Brown <david.brown@hesbynett.no> - 2018-12-12 09:09 +0100
Re: snprintf return value Clifford Heath <no.spam@please.net> - 2018-12-12 21:38 +1100
Re: snprintf return value Les Cargill <lcargill99@comcast.com> - 2018-12-30 11:23 -0600
Re: snprintf return value Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2018-12-11 00:47 +0100
Re: snprintf return value Clifford Heath <no.spam@please.net> - 2018-12-11 13:31 +1100
csiph-web