Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

glibc: asprintf and asnprintf

543 views
Skip to first unread message

Scott

unread,
Aug 21, 2018, 3:29:35 AM8/21/18
to
This is an OT article, being more about gnu libc than C-the-language,
so feel free to move on.

I'm moving one of my everyday boxes directly from XP32(!) to 10x64, so
I'm updating a lot of the little tools I've written over the years.
Rebuilding them with a fresh copy of Cygwin, I run into a compiler
warning that asprintf is undefined.

Well...turns out, asprintf isn't in any standard, it just happens to
have been in every libc I've used in the past decade or so. Now it
seems somebody noticed, and now its prototype hides behinds a
conditional. Sigh. So I give it the big -D that it wants so bad, clean
compile, clean link, clean test. Yay.

Looking further into it, the gnu folks seem to be on the road to
deprecating asprintf in favor of a newer function, asnprintf.

asnprintf is like a hybrid of asprintf with snprintf. Like snprintf,
it takes a user buffer and fills it up to the given limit. If the
output is bigger, though, then it acts like asprintf and malloc's a
buffer to contain the entire output.

It's kind of a shorthand for when you don't really want to malloc, but
you're not certain that you won't have to. I guess that solves
somebody's problem, but here's what else I see.

First, it doesn't fix what's wrong with asprintf, in that a crafted
attack can still exhaust the allocation pool. Don't get me wrong, I
love asprintf and it beats the pants off of sprintf, but it's true.

Second, asnprintf's return value might point to your buffer, or it
might point to the heap. Whatever else you had in mind, now you've got
extra work in order to dispose of that pointer properly.

Third, if you *do* want to avoid point 2 above, you'd need to know how
to call asnprintf in a way that forces it to act like asprintf every
time. That's a problem because (3a) there's no documentation to speak
of. No man page or info node I could find. (Well, no...cygwin's printf
page says that asnprintf acts like snprintf, which acts like sprintf,
and doesn't say much else.)

I found a vague description and a header file comment that assumes
that you want to snprintf-with-safety, but no mention on how to make
asnprintf behave like asprintf where asprintf is really what you want.
Yes...there is source. There are a lot of #ifdefs in that source. I'll
need a minute to figure out what it means.

Now...is it just me, or do I correctly sense that GNU-like thinking
has a historical predisposition towards deploying implementations
before the documentation is done? Am I too optimistic to think that
there's even an intention of creating complete documentation at all?

Melzzzzz

unread,
Aug 21, 2018, 3:41:25 AM8/21/18
to
CONFORMING TO
These functions are GNU extensions, not in C or POSIX.
They are also available under *BSD. The FreeBSD implementation sets
strp to NULL on error.
SYNOPSIS
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdio.h>

Nowhere I read that they would be deprecated?
And I am on bleeding edge distro...
--
press any key to continue or any other to quit...

Ben Bacarisse

unread,
Aug 21, 2018, 7:22:02 AM8/21/18
to
nob...@example.org (Scott) writes:
<snip>
> Looking further into it, the gnu folks seem to be on the road to
> deprecating asprintf in favor of a newer function, asnprintf.

It would help others if you gave a source for this. I can't find any
information about this change in direction, and without a source for
your information I have no idea if it's a rock solid plan, a vague
rumour or a dead proposal.

The current glibc sources have make reference to asnprintf.

> asnprintf is like a hybrid of asprintf with snprintf. Like snprintf,
> it takes a user buffer and fills it up to the given limit. If the
> output is bigger, though, then it acts like asprintf and malloc's a
> buffer to contain the entire output.

I've only been able to find fleeting references to what asnprintf is
supposed to do and they are contradictory. My advice would be to avoid
it until it is well documented.

<snip>
> Now...is it just me, or do I correctly sense that GNU-like thinking
> has a historical predisposition towards deploying implementations
> before the documentation is done? Am I too optimistic to think that
> there's even an intention of creating complete documentation at all?

Not too optimistic, no. The fact that it has not happened would tell me
to avoid this function for now.

I found some conflicting statements about it[1,2] and also a post[3]
about a suggestion to add it to "newlib" in cygwin. It explains a
little of the thinking behind the proposal but it is far from
definitive.

[1] https://www.intel.com/content/www/us/en/programmable/documentation/lro1419794938488/mwh1416946758774/mwh1416946771586/mwh1416946790611/kju1484076804980.html

[2] https://www.ijs.si/software/snprintf/

[3] https://lists.gnu.org/archive/html/bug-gnulib/2007-03/msg00211.html

--
Ben.

Jorgen Grahn

unread,
Aug 21, 2018, 8:07:09 AM8/21/18
to
On Tue, 2018-08-21, Scott wrote:
> This is an OT article, being more about gnu libc than C-the-language,
> so feel free to move on.
>
> I'm moving one of my everyday boxes directly from XP32(!) to 10x64, so
> I'm updating a lot of the little tools I've written over the years.
> Rebuilding them with a fresh copy of Cygwin, I run into a compiler
> warning that asprintf is undefined.
>
> Well...turns out, asprintf isn't in any standard, it just happens to
> have been in every libc I've used in the past decade or so. Now it
> seems somebody noticed, and now its prototype hides behinds a
> conditional. Sigh. So I give it the big -D that it wants so bad, clean
> compile, clean link, clean test. Yay.

You may want to read <features.h>. The glibc headers try not to
expose too many non-standard features unless you explicitly ask for
them. In this case I guess you must have asked for ISO C, and so
<stdio.h> didn't automatically give you asprintf(). Makes sense.

...
> I found a vague description and a header file comment that assumes
> that you want to snprintf-with-safety, but no mention on how to make
> asnprintf behave like asprintf where asprintf is really what you want.
> Yes...there is source. There are a lot of #ifdefs in that source. I'll
> need a minute to figure out what it means.
>
> Now...is it just me, or do I correctly sense that GNU-like thinking
> has a historical predisposition towards deploying implementations
> before the documentation is done?

Not my experience, but I suppose that varies with your definition of
"GNU-like thinking". IME, if a notable function is available in the
GNU libc, there's also a good man page for it.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Nick Bowler

unread,
Aug 21, 2018, 11:44:09 AM8/21/18
to
On Tue, 21 Aug 2018 07:29:24 +0000, Scott wrote:
> This is an OT article, being more about gnu libc than C-the-language,
> so feel free to move on.
[...]
> Looking further into it, the gnu folks seem to be on the road to
> deprecating asprintf in favor of a newer function, asnprintf.
>
> asnprintf is like a hybrid of asprintf with snprintf. Like snprintf,
> it takes a user buffer and fills it up to the given limit. If the
> output is bigger, though, then it acts like asprintf and malloc's a
> buffer to contain the entire output.
[...]
> I found a vague description and a header file comment that assumes
> that you want to snprintf-with-safety, but no mention on how to make
> asnprintf behave like asprintf where asprintf is really what you want.
> Yes...there is source. There are a lot of #ifdefs in that source. I'll
> need a minute to figure out what it means.
>
> Now...is it just me, or do I correctly sense that GNU-like thinking
> has a historical predisposition towards deploying implementations
> before the documentation is done? Am I too optimistic to think that
> there's even an intention of creating complete documentation at all?

The GNU libc mailing list[1] is the normal place to ask questions about
GNU libc.

But I'm not sure these questions have anything to do with GNU libc...

There is no "asnprintf" function in the GNU C library that I can find;
it is neither described in the manual nor present in the latest sources.

There is also no indication in the manual[2] for the GNU C library
that asprintf is deprecated in any way. However I suggest avoiding
it, if practical, since asprintf is a nonstandard extension.

[1] libc...@sourceware.org
[2] https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-asprintf

fir

unread,
Aug 21, 2018, 3:51:26 PM8/21/18
to
W dniu wtorek, 21 sierpnia 2018 09:29:35 UTC+2 użytkownik Scott napisał:
>
> I'm moving one of my everyday boxes directly from XP32(!) to 10x64, so

dont betray the win5 community.. i got them both win5 (32 bit) and win10 (64 bit) but still preffer win5 (and win 10 covers in dust like 3 years now? )

[and im very angy for anny atempts of the word to making xp deprecated, older dont mean worse]

Scott

unread,
Aug 21, 2018, 9:02:17 PM8/21/18
to
On Tue, 21 Aug 2018 12:51:11 -0700 (PDT), fir <profes...@gmail.com>
wrote:

>[and im very angy for anny atempts of the word to making xp deprecated, old=
>er dont mean worse]

Fir, I think that's the first thing I've heard from you that I both
understand and agree with.

Scott

unread,
Aug 21, 2018, 9:02:17 PM8/21/18
to
On Tue, 21 Aug 2018 15:43:56 -0000 (UTC), Nick Bowler
<nbo...@draconx.ca> wrote:

>The GNU libc mailing list[1] is the normal place to ask questions about
>GNU libc.

True. Ranting in clc is less likely to get me kicked off the list,
though. I heard that the moderator here is a pushover.

>There is also no indication in the manual[2] for the GNU C library
>that asprintf is deprecated in any way. However I suggest avoiding
>it, if practical, since asprintf is a nonstandard extension.

But it's a *really* *cool* extension! But also easy enough to fake, if
not inexpensively.

Scott

unread,
Aug 21, 2018, 9:02:17 PM8/21/18
to
On 21 Aug 2018 12:06:56 GMT, Jorgen Grahn <grahn...@snipabacken.se>
wrote:

>You may want to read <features.h>. The glibc headers try not to
>expose too many non-standard features unless you explicitly ask for
>them. In this case I guess you must have asked for ISO C, and so
><stdio.h> didn't automatically give you asprintf(). Makes sense.

See, I'd have guessed that putting -std=gnu99 in CFLAGS would have
told the compiler to haul in the gnu stuff. Joke's on me this time.

>Not my experience, but I suppose that varies with your definition of
>"GNU-like thinking". IME, if a notable function is available in the
>GNU libc, there's also a good man page for it.

FSVO "good". I've noticed a stylistic difference between FreeBSD's
pages and Linux's pages, personally I find the former to be generally
more concise. There's a tangible discord between GNU thinking and
Berkeley thinking. (Then there's AT&T thinking, but I've never
suffered the indignity of using a descendant of SysV.)

Scott

unread,
Aug 21, 2018, 9:02:17 PM8/21/18
to
On Tue, 21 Aug 2018 12:21:49 +0100, Ben Bacarisse
<ben.u...@bsb.me.uk> wrote:

>nob...@example.org (Scott) writes:
><snip>
>> Looking further into it, the gnu folks seem to be on the road to
>> deprecating asprintf in favor of a newer function, asnprintf.
>
>It would help others if you gave a source for this. I can't find any
>information about this change in direction, and without a source for
>your information I have no idea if it's a rock solid plan, a vague
>rumour or a dead proposal.

Nothing I can point to, just a feeling. Sort of like when I first
heard about systemd. That didn't seem like a good idea at the time,
and IMO still isn't. But here we are.

As far as movement, the earliest reference I found was ca.2000, and it
doesn't seem to have moved a lot since then.

>I've only been able to find fleeting references to what asnprintf is
>supposed to do and they are contradictory. My advice would be to avoid
>it until it is well documented.

That's good advice.

Tim Rentsch

unread,
Aug 22, 2018, 1:42:15 AM8/22/18
to
Do you think it has to be expensive? With a little bit of care, I
think one could write a drop-in replacement based on snprintf(), where
typical uses would be done with one malloc() call, one snprintf()
call, and one realloc() call. If the problem were mine, I would
rather spend an hour or two producing an ISO-standard-based component
than worry about tracking down a possibly-soon-to-be-deprecated and
library-supplier-dependent utility function.

Scott

unread,
Aug 22, 2018, 2:57:02 AM8/22/18
to
On Tue, 21 Aug 2018 22:42:02 -0700, Tim Rentsch
<t...@alumni.caltech.edu> wrote:

>nob...@example.org (Scott) writes:
>
>> On Tue, 21 Aug 2018 15:43:56 -0000 (UTC), Nick Bowler
>> <nbo...@draconx.ca> wrote:
>>
>>> There is also no indication in the manual[2] for the GNU C library
>>> that asprintf is deprecated in any way. However I suggest avoiding
>>> it, if practical, since asprintf is a nonstandard extension.
>>
>> But it's a *really* *cool* extension! But also easy enough to fake, if
>> not inexpensively.
>
>Do you think it has to be expensive? With a little bit of care, I
>think one could write a drop-in replacement based on snprintf(), where
>typical uses would be done with one malloc() call, one snprintf()
>call, and one realloc() call. If the problem were mine, I would

For a clean C99 implementation snprintf would be the obvious choice.
My first thought is for a snprintf call against a small auto buffer,
then either (a) strdup or (b) malloc and a 2nd call to snprintf. I'm
not seeing how to do it with only one call to snprintf, though.

snprintf itself is a lovely thing; I wager it's a lot easier to build
asprintf on snprintf than it would have been to build snprintf on
fprintf. It wasn't that long ago I used a library with no snprintf.
How did we survive?

>rather spend an hour or two producing an ISO-standard-based component
>than worry about tracking down a possibly-soon-to-be-deprecated and
>library-supplier-dependent utility function.

Mmm. Maybe. asprintf has been in the GNU library for ~25 years or so,
so unlikely to go away soon. I probably misread the situation before
looking into it more. Why cygwin started hiding it behind _GNU_SOURCE
is a poser, but cygwin is weird.

fir

unread,
Aug 22, 2018, 9:49:40 AM8/22/18
to
you agree, but you still betrayed xp.. :C
its sad

Ben Bacarisse

unread,
Aug 22, 2018, 10:18:14 AM8/22/18
to
nob...@example.org (Scott) writes:

> On Tue, 21 Aug 2018 22:42:02 -0700, Tim Rentsch
> <t...@alumni.caltech.edu> wrote:
>
>>nob...@example.org (Scott) writes:
>>
>>> On Tue, 21 Aug 2018 15:43:56 -0000 (UTC), Nick Bowler
>>> <nbo...@draconx.ca> wrote:
>>>
>>>> There is also no indication in the manual[2] for the GNU C library
>>>> that asprintf is deprecated in any way. However I suggest avoiding
>>>> it, if practical, since asprintf is a nonstandard extension.
>>>
>>> But it's a *really* *cool* extension! But also easy enough to fake, if
>>> not inexpensively.
>>
>>Do you think it has to be expensive? With a little bit of care, I
>>think one could write a drop-in replacement based on snprintf(), where
>>typical uses would be done with one malloc() call, one snprintf()
>>call, and one realloc() call. If the problem were mine, I would
>
> For a clean C99 implementation snprintf would be the obvious choice.
> My first thought is for a snprintf call against a small auto buffer,
> then either (a) strdup or (b) malloc and a 2nd call to snprintf. I'm
> not seeing how to do it with only one call to snprintf, though.

I think the "typical uses" Tim it talking about are ones where it's
worth calculating an upper bound on the required size (or where you can
simply guess). In those cases a malloc, snprintf followed by a realloc
to shrink would do.

<snip>
>>rather spend an hour or two producing an ISO-standard-based component
>>than worry about tracking down a possibly-soon-to-be-deprecated and
>>library-supplier-dependent utility function.
>
> Mmm. Maybe. asprintf has been in the GNU library for ~25 years or so,
> so unlikely to go away soon. I probably misread the situation before
> looking into it more. Why cygwin started hiding it behind _GNU_SOURCE
> is a poser, but cygwin is weird.

I would be surprised if it's just cygwin, but you don't give the gcc
flags you used so maybe it is. In general, it's useful to be told when
you are using a non-standard function or for the code or the build to
make it explicit. The old habit that some compilers had of just giving
you everything including extensions and the kitchen sink was never a
good idea.

--
Ben.

Tim Rentsch

unread,
Aug 22, 2018, 2:22:41 PM8/22/18
to
nob...@example.org (Scott) writes:

> On Tue, 21 Aug 2018 22:42:02 -0700, Tim Rentsch
> <t...@alumni.caltech.edu> wrote:
>
>> nob...@example.org (Scott) writes:
>>
>>> On Tue, 21 Aug 2018 15:43:56 -0000 (UTC), Nick Bowler
>>> <nbo...@draconx.ca> wrote:
>>>
>>>> There is also no indication in the manual[2] for the GNU C library
>>>> that asprintf is deprecated in any way. However I suggest avoiding
>>>> it, if practical, since asprintf is a nonstandard extension.
>>>
>>> But it's a *really* *cool* extension! But also easy enough to fake, if
>>> not inexpensively.
>>
>> Do you think it has to be expensive? With a little bit of care, I
>> think one could write a drop-in replacement based on snprintf(), where
>> typical uses would be done with one malloc() call, one snprintf()
>> call, and one realloc() call. If the problem were mine, I would
>
> For a clean C99 implementation snprintf would be the obvious choice.
> My first thought is for a snprintf call against a small auto buffer,
> then either (a) strdup or (b) malloc and a 2nd call to snprintf. I'm
> not seeing how to do it with only one call to snprintf, though.

The key phrase is "typical uses". Probably most calls to asprintf()
need two thousand bytes or less. Do an initial malloc() of 4k bytes,
snprintf() into that allocated memory, and check the results: if it
fit, just realloc(), and done. If it didn't fit then of course we
need to get a larger buffer and do a second snprintf(), but presumably
those are rare enough so it won't matter very much. Obviously schemes
like this one need some testing/tuning to see what the effects are on
memory allocation patterns, but in modern environments grabbing a few
thousand bytes of memory and then almost immediately giving most of it
back seems unlikely to cause any sort of serious problem.

>> rather spend an hour or two producing an ISO-standard-based component
>> than worry about tracking down a possibly-soon-to-be-deprecated and
>> library-supplier-dependent utility function.
>
> Mmm. Maybe. asprintf has been in the GNU library for ~25 years or so,
> so unlikely to go away soon. I probably misread the situation before
> looking into it more. Why cygwin started hiding it behind _GNU_SOURCE
> is a poser, but cygwin is weird.

Whether it's a good choice in your circumstances I will leave up
to you. For me, given the low cost, I would remove the external
dependency so I never have to bother with it again (or worry if I
would have to). Also, another factor here is having to define the
_GNU_SOURCE trigger, which I always try to avoid if possible. The
way the gnu include files are set up, these things are always
either all or nothing, and inevitably "all" means dragging in some
things that I didn't know about and usually don't want. If the
gnu extensions could be gotten by, eg, #include <gnuio.h>, rather
than through <stdio.h> with _GNU_SOURCE defined, it might be a
different story, but the all-or-nothing kinds of choices always
feel like beartraps just waiting to grab me and pull me down the
rabbit hole.

Tim Rentsch

unread,
Aug 22, 2018, 2:35:53 PM8/22/18
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> nob...@example.org (Scott) writes:
>
>> On Tue, 21 Aug 2018 22:42:02 -0700, Tim Rentsch
>> <t...@alumni.caltech.edu> wrote:
>>
>>> nob...@example.org (Scott) writes:
>>>
>>>> On Tue, 21 Aug 2018 15:43:56 -0000 (UTC), Nick Bowler
>>>> <nbo...@draconx.ca> wrote:
>>>>
>>>>> There is also no indication in the manual[2] for the GNU C library
>>>>> that asprintf is deprecated in any way. However I suggest avoiding
>>>>> it, if practical, since asprintf is a nonstandard extension.
>>>>
>>>> But it's a *really* *cool* extension! But also easy enough to fake, if
>>>> not inexpensively.
>>>
>>> Do you think it has to be expensive? With a little bit of care, I
>>> think one could write a drop-in replacement based on snprintf(), where
>>> typical uses would be done with one malloc() call, one snprintf()
>>> call, and one realloc() call. If the problem were mine, I would
>>
>> For a clean C99 implementation snprintf would be the obvious choice.
>> My first thought is for a snprintf call against a small auto buffer,
>> then either (a) strdup or (b) malloc and a 2nd call to snprintf. I'm
>> not seeing how to do it with only one call to snprintf, though.
>
> I think the "typical uses" Tim it talking about are ones where its
> worth calculating an upper bound on the required size (or where you can
> simply guess). In those cases a malloc, snprintf followed by a realloc
> to shrink would do.

My idea was more simple-minded - just do the first malloc() with
a constant size, somewhere in the low-to-middle single digits of
thousands of bytes.

Probably we could get better estimates by scanning the format
string and making guesses for each of the various conversion
sequences. I didn't think of that. On systems without much
memory that will very likely give better results. On typical
desktops, or laptops, or even tablets, the time spent scanning
might not help enough to be worth it. But certainly your idea
has more thought behind it than mine did.

Jorgen Grahn

unread,
Aug 22, 2018, 3:14:36 PM8/22/18
to
On Wed, 2018-08-22, Scott wrote:
> On 21 Aug 2018 12:06:56 GMT, Jorgen Grahn <grahn...@snipabacken.se>
> wrote:
>
>>You may want to read <features.h>. The glibc headers try not to
>>expose too many non-standard features unless you explicitly ask for
>>them. In this case I guess you must have asked for ISO C, and so
>><stdio.h> didn't automatically give you asprintf(). Makes sense.
>
> See, I'd have guessed that putting -std=gnu99 in CFLAGS would have
> told the compiler to haul in the gnu stuff.

I thought so too, but it seems I was wrong. I had to say -D_GNU_SOURCE
to have it pulled in.

At the same time, I'm pretty sure -std=gnu/c affects the processing of
standard includes in /some/ way.

Scott

unread,
Aug 22, 2018, 9:29:31 PM8/22/18
to
On Wed, 22 Aug 2018 11:22:29 -0700, Tim Rentsch
<t...@alumni.caltech.edu> wrote:

>nob...@example.org (Scott) writes:
>> For a clean C99 implementation snprintf would be the obvious choice.
>> My first thought is for a snprintf call against a small auto buffer,
>> then either (a) strdup or (b) malloc and a 2nd call to snprintf. I'm
>> not seeing how to do it with only one call to snprintf, though.
>
>The key phrase is "typical uses". Probably most calls to asprintf()
>need two thousand bytes or less. Do an initial malloc() of 4k bytes,
>snprintf() into that allocated memory, and check the results: if it
>fit, just realloc(), and done. If it didn't fit then of course we
>need to get a larger buffer and do a second snprintf(), but presumably
>those are rare enough so it won't matter very much. Obviously schemes
>like this one need some testing/tuning to see what the effects are on
>memory allocation patterns, but in modern environments grabbing a few
>thousand bytes of memory and then almost immediately giving most of it
>back seems unlikely to cause any sort of serious problem.

Ah, I see where you're coming from. Hard to say if one approach beats
the other, it's probably splitting hairs if so. Chasing that optimal
init buffer size, though, that could turn into a rabbit hole of its
own.

>gnu extensions could be gotten by, eg, #include <gnuio.h>, rather
>than through <stdio.h> with _GNU_SOURCE defined, it might be a
>different story, but the all-or-nothing kinds of choices always
>feel like beartraps just waiting to grab me and pull me down the
>rabbit hole.

That's kind of what I mean by "GNU thinking". Not that the gnu
toolchain isn't remarkably good for the price, but it has definite
issues about playing nice with other vendors.

Tim Rentsch

unread,
Aug 23, 2018, 2:16:11 PM8/23/18
to
nob...@example.org (Scott) writes:

> On Wed, 22 Aug 2018 11:22:29 -0700, Tim Rentsch
> <t...@alumni.caltech.edu> wrote:
>
>> nob...@example.org (Scott) writes:
>>
>>> For a clean C99 implementation snprintf would be the obvious choice.
>>> My first thought is for a snprintf call against a small auto buffer,
>>> then either (a) strdup or (b) malloc and a 2nd call to snprintf. I'm
>>> not seeing how to do it with only one call to snprintf, though.
>>
>> The key phrase is "typical uses". Probably most calls to asprintf()
>> need two thousand bytes or less. Do an initial malloc() of 4k bytes,
>> snprintf() into that allocated memory, and check the results: if it
>> fit, just realloc(), and done. If it didn't fit then of course we
>> need to get a larger buffer and do a second snprintf(), but presumably
>> those are rare enough so it won't matter very much. Obviously schemes
>> like this one need some testing/tuning to see what the effects are on
>> memory allocation patterns, but in modern environments grabbing a few
>> thousand bytes of memory and then almost immediately giving most of it
>> back seems unlikely to cause any sort of serious problem.
>
> Ah, I see where you're coming from. Hard to say if one approach beats
> the other, it's probably splitting hairs if so. Chasing that optimal
> init buffer size, though, that could turn into a rabbit hole of its
> own.

Yeah. That goes along with my Keep It Stupid, Stupid, suggestion
of just using a constant initial value.

>> gnu extensions could be gotten by, eg, #include <gnuio.h>, rather
>> than through <stdio.h> with _GNU_SOURCE defined, it might be a
>> different story, but the all-or-nothing kinds of choices always
>> feel like beartraps just waiting to grab me and pull me down the
>> rabbit hole.
>
> That's kind of what I mean by "GNU thinking". Not that the gnu
> toolchain isn't remarkably good for the price, but it has definite
> issues about playing nice with other vendors.

I'm sure it's just fine for lots of people. Me, I've gotten
snared in too many beartraps to think opening that Pandora's
box is a smart move.

already...@yahoo.com

unread,
Aug 23, 2018, 5:08:35 PM8/23/18
to
Very off topic here, but do you happen to know that SMB1 protocol is terminally broken from security perspective and that WinXP does not support anything better?
So, WinXP as an isolated box is mostly o.k. [if we ignore the fact that it does not support PCIe message signaling interrupts which is a cornerstone of majority of add-on cards designed in last 10-12 years] but WinXP in corporate network, if its user insists on being able to use file sharing and admins are sufficiently stupid to agree, will downgrade the security of the whole network.

already...@yahoo.com

unread,
Aug 23, 2018, 5:11:34 PM8/23/18
to
Nitpick - vsnprintf, not snprintf. snprinf is not suitable.


Chris M. Thomasson

unread,
Aug 23, 2018, 6:32:44 PM8/23/18
to
Yikes!

Tim Rentsch

unread,
Aug 24, 2018, 12:52:02 AM8/24/18
to
Yes. I expect anyone following the conversation already
understood that.

Scott

unread,
Aug 24, 2018, 1:24:52 AM8/24/18
to
On Thu, 23 Aug 2018 14:11:23 -0700 (PDT), already...@yahoo.com
wrote:

>Nitpick - vsnprintf, not snprintf. snprinf is not suitable.

I think anyone following along would have made that leap by now.

But your homework now is to implement a vsnprintf on top of snprintf.
Not to show that it's suitable, but to show that it's possible.

Tim Rentsch

unread,
Aug 27, 2018, 10:08:16 PM8/27/18
to
I was intrigued by this statement, and looked into it a little
bit. (To be specific, on my big linux server, which runs an
Ubuntu 16 something distribution.)

My conclusion is, the gnu/c distinction does make a difference for
some third-party packages but mostly does not make a difference for
C standard headers. I found some stuff in <stdio.h> that _looked_
like it was going to be different, but none of what I tried was
able to produce that. One case where it looks pretty sure there is
a difference is <math.h> functions, which IIANM can be expanded
inline under 'gnu' but not under 'c' (and which has consequences
for setting of errno, according to what I read). So although it
seems clear that gnu-vs-c could impact what happens with standard
headers, AFAICT the actual differences are very close to zero,
if not actually zero.

Disclaimer: please don't consider any of the above authoritative.
I did a little investigating and poked around, but I very easily
could have missed something that would invalidate what I thought
I found out.

Jorgen Grahn

unread,
Aug 28, 2018, 1:57:45 AM8/28/18
to
Looking again, I was thinking about things like this in <features.h>:

/* These are defined by the user (or the compiler)
to specify the desired environment:

__STRICT_ANSI__ ISO Standard C.
...
_GNU_SOURCE All of the above, plus GNU extensions.
_DEFAULT_SOURCE The default set of features (taking precedence over
__STRICT_ANSI__).
...
The `-ansi' switch to the GNU C compiler, and standards conformance
options such as `-std=c99', define __STRICT_ANSI__. If none of
these are defined, or if _DEFAULT_SOURCE is defined, the default is
to have _POSIX_SOURCE set to one and _POSIX_C_SOURCE set to
200809L, as well as enabling miscellaneous functions from BSD and
SVID. If more than one of these are defined, they accumulate. For
example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE together
give you ISO C, 1003.1, and 1003.2, but nothing else.

I cannot on short notice come up with a real example where all this
makes a difference. I know I have sometimes used -std=c99
-D_something to get access to certain functions, and at other times
-std=gnu99.

Perhaps the C standard headers like <stdio.h> are excluded from this
system, so that -std=foo affects the contents of pure Unix headers
like <netdb.h>, but not C headers like <stdio.h>, even though Unix
puts extensions in the latter, too.

Ben Bacarisse

unread,
Aug 28, 2018, 6:14:45 AM8/28/18
to
Jorgen Grahn <grahn...@snipabacken.se> writes:

> On Tue, 2018-08-28, Tim Rentsch wrote:
>> Jorgen Grahn <grahn...@snipabacken.se> writes:
>>
>>> On Wed, 2018-08-22, Scott wrote:
>>>
>>>> On 21 Aug 2018 12:06:56 GMT, Jorgen Grahn <grahn...@snipabacken.se>
>>>> wrote:
>>>>
>>>>> You may want to read <features.h>. The glibc headers try not to
>>>>> expose too many non-standard features unless you explicitly ask for
>>>>> them. In this case I guess you must have asked for ISO C, and so
>>>>> <stdio.h> didn't automatically give you asprintf(). Makes sense.
>>>>
>>>> See, I'd have guessed that putting -std=gnu99 in CFLAGS would have
>>>> told the compiler to haul in the gnu stuff.
>>>
>>> I thought so too, but it seems I was wrong. I had to say -D_GNU_SOURCE
>>> to have it pulled in.
>>>
>>> At the same time, I'm pretty sure -std=gnu/c affects the processing of
>>> standard includes in /some/ way.
<snip>
>> My conclusion is, the gnu/c distinction does make a difference for
>> some third-party packages but mostly does not make a difference for
>> C standard headers.
<snip>
Unless I've missed some context by jumping into this thread, it seems
clear that the gnu/c setting does affect <stdio.h>. This file

#include <stdio.h>
int fileno = 42;

compiles with gcc -std=c11 -c but not with gcc -std=gnu11 -c (and the
same for c99 and c90) because in GNU C <stdio.h> defines the POSIX
function 'int fileno(FILE *);'.

--
Ben.

Jorgen Grahn

unread,
Aug 29, 2018, 1:30:54 AM8/29/18
to
You didn't misunderstand; you give a relevant example.

Looking again, and re-reading the features.h quote, it's like this in
the libc here:

function header ifdef to use it
--------------------------------------------------
fileno() <stdio.h> __USE_POSIX -std=gnu99
asprintf() <stdio.h> __USE_GNU -D_GNU_SOURCE

So fileno() is a POSIX thing; asprintf() is classified as GNU (for
unclear reasons; the man page notes it's also in BSD).

What confused me was that -std=gnu99 activates the POSIX and BSD parts
of the libc, but not the GNU parts. That's surprising.

Tim Rentsch

unread,
Aug 31, 2018, 8:15:00 AM8/31/18
to
Jorgen Grahn <grahn...@snipabacken.se> writes:

> On Tue, 2018-08-28, Tim Rentsch wrote:
>
>> [ on -std=gnuNN vs -std=cNN ]
Ahh, I see. I was focused on changes but you are (also) interested
in additions. An idea for how to discover those (for <stdio.h>,
but the same idea could be applied to other headers):

echo '#include <stdio.h>' | gcc -std=c99 -E - | suitable-filter > a
echo '#include <stdio.h>' | gcc -std=gnu99 -E - | suitable-filter > b
diff a b | different-suitable-filter

Running that and cleaning up the output, I got this list (with '...'
put in for function parameter lists):

typedef __gnuc_va_list va_list;
typedef __off_t off_t;
typedef __ssize_t ssize_t;
extern int renameat( ... );
extern char *tmpnam_r( ... );
extern char *tempnam( ... );
extern int fflush_unlocked( ... );
extern FILE *fdopen( ... );
extern FILE *fmemopen( ... );
extern FILE *open_memstream( ... );
extern void setbuffer( ... );
extern void setlinebuf( ... );
extern int vdprintf( ... );
extern int dprintf( ... );
extern int getc_unlocked( ... );
extern int getchar_unlocked( ... );
extern int fgetc_unlocked( ... );
extern int fputc_unlocked( ... );
extern int putc_unlocked( ... );
extern int putchar_unlocked( ... );
extern int getw( ... );
extern int putw( ... );
extern __ssize_t __getdelim( ... );
extern __ssize_t getdelim( ... );
extern __ssize_t getline( ... );
extern size_t fread_unlocked( ... );
extern size_t fwrite_unlocked( ... );
extern int fseeko( ... );
extern __off_t ftello( ... );
extern void clearerr_unlocked( ... );
extern int feof_unlocked( ... );
extern int ferror_unlocked( ... );
extern int sys_nerr;
extern const char *const sys_errlist[];
extern int fileno( ... );
extern int fileno_unlocked( ... );
extern FILE *popen( ... );
extern int pclose( ... );
extern char *ctermid( ... );
extern void flockfile( ... );
extern int ftrylockfile( ... );
extern void funlockfile( ... );

I have a new tool for my bag.. thank you.
0 new messages