On 10/04/2016 06:21 PM, Joseph Myers wrote:
On Tue, 4 Oct 2016, Martin Sebor wrote:
I've built the sparc-sun-solaris2.12 toolchain and reproduced these
warnings. They are vestiges of those I saw and some of which I fixed
before. The problem is that %lc expects a wint_t argument which on
this target is an alias for long in but the argument of 0 has type
int. The warning is coming out of the -Wformat checker which doesn't
seem to care that int and long have the same size. I've committed
r240758 that should fix the remaining warnings of this kind but long
term I think GCC should change to avoid warning in this case (Clang
doesn't).
Well, typically cases where one of long and int is passed and the other is
expected, but they have the same size, are bugs waiting to happen when the
code is built on a 64-bit system. That is, they *should* warn.
Typically, yes. In the case of wchar_t (or int) and wint_t I don't
think it's helpful. Consider this case from my comment #5 on bug
72858. I don't think there is any point in issuing a warning here.
On the majority of targets they either all are or promote to a type
of the same size, don't they?
$ cat t.c && gcc -S -Wall -m32 t.c
typedef __WCHAR_TYPE__ wchar_t;
void f (const wchar_t *ws)
{
__builtin_printf ("%lc", *ws);
}
t.c: In function ‘f’:
t.c:5:24: warning: format ‘%lc’ expects argument of type ‘wint_t’, but
argument 2 has type ‘wchar_t {aka const long int}’ [-Wformat=]
__builtin_printf ("%lc", *ws);
~~^ ~~~
%ld
There have been arguments that we should go further and warn for e.g. %zu
with a type that happens to be the same as size_t but doesn't use the
size_t typedef (or sizeof etc.), %td for something that happens to be the
same as ptrdiff_t but doesn't use the typedef (or pointer difference
etc.), etc. - which would get many similar cases of bugs waiting to happen
on a different system, but is also tricker because you need to decide
whether a given type is logically size_t etc. or not - code could validly
use autoconf to identify the underlying type, or use __SIZE_TYPE__, or use
an expression mixing size_t with other types, or in the case of %j*
(intmax_t) use the INTMAX_C macro to construct constants. That probably
*would* need an option to disable just those format warnings (whereas I
don't see the need for such an option for the case of mixing int and
long).
I would view it useful if GCC warned on %zu with an argument that's
not size_t, and similarly for other directives and typedefs, for the
reason you mention. But I don't think the same rationale applies
to warning on %lc with wchar_t or int arguments.
Martin