On 01/04/2018 01:30 AM, Jakub Jelinek wrote:
On Wed, Jan 03, 2018 at 05:00:41PM -0700, Martin Sebor wrote:
This is an example where having a solution for bug 78014 would
be helpful. I.e., a -Wformat checker to help enforce the use
No, because %zu isn't portable enough for all the hosts we support.
GCC could mitigate all these portability pitfalls by providing
its own versions of the functions (I suggested gcc_printf the
last time we discussed this subject). libiberty already does
this for a small subset of the portability problems in some of
the standard functions (including vsprintf), so this would be
a natural extension of that approach.
What we could do is define SIZE_T_PRINT_UNSIGNED and similar macros,
to "%zu" on POSIX compliant targets and something else depending on what we
find out during configure (e.g. using templates to find out if size_t
on the host is unsigned {int,long,long long} or something different
(I hope we don't support msp430 as host where size_t is unsigned __int20).
We could do that, but it would be a far inferior solution to
defining our own printf. Take another look at what using these
awful macros does to readability:
fprintf (dump_file, " Directive %u at offset "
HOST_WIDE_INT_PRINT_UNSIGNED ": \"%.*s\", "
"length = " HOST_WIDE_INT_PRINT_UNSIGNED "\n",
dir.dirno,
(unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
(int)dir.len, dir.beg, dir.len);
With GCC's own fprintf, all this ugliness could go away. In C++ 11
gcc_fprintf could even be a variadic function template that would
completely obviate the need for length modifiers or even conversion
specifiers. With it, the above could become as simple as:
gcc_fprintf (dump_file,
" Directive %u at offset %u: \"%.*s\", length = %u \n",
dir.dirno, dir.beg - info.fmtstr,
dir.len, dir.beg, dir.len);
regardless of the types of the arguments.
Martin
While in theory GCC could handle some PR78014 cases (but only very early
before any folding) for size_t, HOST_WIDE_INT is a define and I don't see
how GCC could argue about portability there.
of %zu instead of %u or %lu (or an explicit cast from size_t)
even on targets size_t is unsigned or unsigned long, respectively.
Jakub