printf("%m") doesn't generate a warning -- shouldn't it?
Dimitry Andric
dim at FreeBSD.org
Tue May 22 10:40:05 UTC 2018
On 21 May 2018, at 15:43, Konstantin Belousov <kostikbel at gmail.com> wrote:
>
> On Mon, May 21, 2018 at 01:19:01PM +0200, Dimitry Andric wrote:
>> On 21 May 2018, at 04:38, Thomas Munro <munro at ip9.org> wrote:
>>>
>>> As discussed on the PostgreSQL[1] and NetBSD mailing lists[2][3],
>>> syslog-like printf("%m") is a GNU extension that doesn't generate a
>>> warning from Clang or GCC on other operating systems even though when
>>> it doesn't actually work. That's because the __printf__ attribute
>>> that our __printflike macro in /usr/include/stdio.h expands to
>>> effectively means "like printf in glibc, allowing %m", not like POSIX
>>> or our actual libc which just prints out "m" when it sees it.
>>>
>>> It'd sure be nice to get a compiler warning on FreeBSD when porting
>>> software that uses that if it doesn't actually work (or ... to support
>>> it).
>>
>> Please submit upstream bug(s) for clang and gcc. It turns out clang has
>> a -Wformat-non-iso warning flag which should warn about this, but I
>> can't get it to emit it:
>>
>> $ cat printf-m.c
>> #include <stdio.h>
>>
>> int main(void)
>> {
>> printf("error: %m\n");
>> return 0;
>> }
>>
>> $ clang -std=c99 -Wformat-non-iso -c printf-m.c
>> <nothing>
>
> Why not add %m instead ? It is very easy and several people did it in
> round-about ways.
Sure, that is certainly a nice thing to have, and let's commit it. But
it's still an upstream bug if an explicit warning flag for non-ISO
printf specifiers doesn't work. I'll take that discussion to the LLVM
bug tracker.
> diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
> index 29fbd95b399..70f5074e2f7 100644
> --- a/lib/libc/stdio/vfprintf.c
> +++ b/lib/libc/stdio/vfprintf.c
> @@ -317,6 +317,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
> int ret; /* return value accumulator */
> int width; /* width from format (%8d), or 0 */
> int prec; /* precision from format; <0 for N/A */
> + int saved_errno;
> char sign; /* sign prefix (' ', '+', '-', or \0) */
> struct grouping_state gs; /* thousands' grouping info */
>
> @@ -466,6 +467,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
> savserr = fp->_flags & __SERR;
> fp->_flags &= ~__SERR;
>
> + saved_errno = errno;
> convbuf = NULL;
> fmt = (char *)fmt0;
> argtable = NULL;
> @@ -776,6 +778,11 @@ reswitch: switch (ch) {
> }
> break;
> #endif /* !NO_FLOATING_POINT */
> + case 'm':
> + cp = strerror(saved_errno);
> + size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
> + sign = '\0';
> + break;
> case 'n':
> /*
> * Assignment-like behavior is specified if the
LGTM.
-Dimitry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 223 bytes
Desc: Message signed with OpenPGP
URL: <http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20180522/e98f60e6/attachment.sig>
More information about the freebsd-hackers
mailing list