Thread: snprintf()
Hello, I've been implementing a type I needed, and happened to be using snprintf(), since I have C99 available. ereport(NOTICE, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("%d", snprintf(NULL, 0, "abc")))); For me, this reports "0". I beieve it should report 3. My system's snprintf() returns 3. I'm using NetBSD. By including postgres.h and fmgr.h, does PostgreSQL replace my system's snprintf() prototype with its own implementation's? Placing stdio.h above those includes appears to have no effect. For reference, the relevant part of C99: 7.19.6.5 2 If n is zero, nothing is written, and s may be a null pointer. 7.19.6.5 3 The snprintf function returns the number of characters that would have been written had n been sufficiently large,not counting the terminating null character, or a neg ative value if an encoding error occurred. Regards, -- Kate
Kate F <kate@cats.meow.at> writes: > ... does PostgreSQL replace my system's snprintf() prototype with > its own implementation's? We do on some platforms where configure decides the system version is deficient ... I don't recall the exact conditions at the moment. I wouldn't really have expected that to happen on any *BSD, but you could look into the generated Makefile.global to find out. > For reference, the relevant part of C99: > 7.19.6.5 2 If n is zero, nothing is written, and s may be a null > pointer. For reference, the relevant part of the Single Unix Spec: If the value of n is zero on a call to snprintf(), anunspecified value less than 1 is returned. So the behavior you'd like to depend on is unportable anyway, and that coding will get rejected if submitted as a Postgres patch. regards, tom lane
On Fri, Feb/ 2/07 10:52:28PM -0500, Tom Lane wrote: > Kate F <kate@cats.meow.at> writes: > > ... does PostgreSQL replace my system's snprintf() prototype with > > its own implementation's? > > We do on some platforms where configure decides the system version > is deficient ... I don't recall the exact conditions at the moment. > I wouldn't really have expected that to happen on any *BSD, but you > could look into the generated Makefile.global to find out. I don't see anything that looks relevant for my Makefile.global; I would be surprised if NetBSD's were overridden too! > > For reference, the relevant part of C99: > > 7.19.6.5 2 If n is zero, nothing is written, and s may be a null > > pointer. > > For reference, the relevant part of the Single Unix Spec: > > If the value of n is zero on a call to snprintf(), an > unspecified value less than 1 is returned. Aha! I do recall either POSIX or SUS defers to C on conflicts... I can't find which, though. If this snprintf() is following SUS behaviour, that's fine. Thank you! > So the behavior you'd like to depend on is unportable anyway, and > that coding will get rejected if submitted as a Postgres patch. Absolutley (and I assume you target C89, too, which does not provide snprintf()). This was just something personal where I happened to use it for convenience. Thank you for checking that - and appologies for posting to the wrong list; that should have been to -bugs! Regards, -- Kate
Kate F <kate@cats.meow.at> writes: > On Fri, Feb/ 2/07 10:52:28PM -0500, Tom Lane wrote: >> I wouldn't really have expected that to happen on any *BSD, but you >> could look into the generated Makefile.global to find out. > I don't see anything that looks relevant for my Makefile.global; I > would be surprised if NetBSD's were overridden too! Sorry for not being specific: the thing to check is whether that file's definition for LIBOBJS includes snprintf.o. If it does, the code in src/port/snprintf.c would get sucked in. If it doesn't, then I confess bafflement as to why snprintf isn't acting as you'd expect on your machine. regards, tom lane
On Fri, Feb/ 2/07 11:20:07PM -0500, Tom Lane wrote: > Kate F <kate@cats.meow.at> writes: > > On Fri, Feb/ 2/07 10:52:28PM -0500, Tom Lane wrote: > >> I wouldn't really have expected that to happen on any *BSD, but you > >> could look into the generated Makefile.global to find out. > > > I don't see anything that looks relevant for my Makefile.global; I > > would be surprised if NetBSD's were overridden too! > > Sorry for not being specific: the thing to check is whether that > file's definition for LIBOBJS includes snprintf.o. If it does, > the code in src/port/snprintf.c would get sucked in. > > If it doesn't, then I confess bafflement as to why snprintf isn't > acting as you'd expect on your machine. Just these: LIBOBJS = copydir.o dirmod.o exec.o noblock.o path.o pipe.o pgsleep.opgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o (More than I expected, actually) I am imagining the compiler (gcc, here) has some flags to explicitly select if C99 (which is what I tested my stand-alone example with) or SUS behaviour is to be used. I'm not really sure how I'd set that, though - I imagine I'd need to recompile the backend with -std=C99? Regards, -- Kate