wchar_t printf() format warning

Jonathan Roelofs jonathan@codesourcery.com
Thu Mar 19 15:51:00 GMT 2015



On 3/19/15 8:40 AM, Joel Sherrill wrote:
>
>
> On 3/18/2015 4:46 PM, Jonathan Roelofs wrote:
>>
>> On 3/18/15 3:29 PM, Joel Sherrill wrote:
>>> Hi
>>>
>>> I am returning to this issue. This appears to be similar to the
>>> intptr_t issue but with wchar_t. We get a printf() warning on
>>> targets where wchar_t is defined is defined as "long int" and
>>> not on targets where it is "int".  This appears to be because
>>> of a conflict in the definition of __WINT_TYPE__ and
>>> __WCHAR_TYPE__ by gcc.  I am open to suggestions on how
>>> to resolve this.
>>>
>>> $ sparc-rtems4.11-gcc -dM -E - </dev/null | grep WCHAR_TYPE
>>> #define __WCHAR_TYPE__ long int
>>> $ i386-rtems4.11-gcc -dM -E - </dev/null | grep WCHAR_TYPE
>>> #define __WCHAR_TYPE__ int
>>> $ sparc-rtems4.11-gcc -dM -E - </dev/null | grep WINT_TYPE
>>> #define __WINT_TYPE__ unsigned int
>>> $ i386-rtems4.11-gcc -dM -E - </dev/null | grep WINT_TYPE
>>> #define __WINT_TYPE__ unsigned int
>>>
>>>
>>> sparc generates this warning but i386 does not:
>>>
>>> $ sparc-rtems4.11-gcc -Wall -c wc.c
>>> wc.c: In function 'f':
>>> wc.c:10:3: warning: format '%lc' expects argument of type 'wint_t', but
>>> argument 4 has type 'wchar_t' [-Wformat=]
>>>      (void)printf("%*s%lc\n", pad, "", wc);
>>>      ^
>>> wc.c:10:3: warning: format '%lc' expects argument of type 'wint_t', but
>>> argument 4 has type 'wchar_t' [-Wformat=]
>>>
>>>
>>> This is the test case:
>>>
>>> =================
>>> #include <stdio.h>
>>> #include <wchar.h>
>>>
>>> void f(void)
>>> {
>>>
>>>     int pad = 10;
>>>     wchar_t wc = 'a';
>>>
>>>     (void)printf("%*s%lc\n", pad, "", wc);
>> §7.19.6.1 7:
>>
>> "l (ell)
>> Specifies that a following d, i, o, u, x, or X conversion specifier
>> applies to a long int or unsigned long int argument; that a following n
>> conversion specifier applies to a pointer to a long int argument; that a
>> following c conversion specifier applies to a wint_t argument; that a
>> following s conversion specifier applies to a pointer to a wchar_t
>> argument; or has no effect on a following a, A, e, E, f, F, g, or G
>> conversion specifier."
>>
>> You need a cast for the last argument: (wint_t)wc
>>
> I left out the disclaimer that this a cut down of code ported to RTEMS from
> FreeBSD.
>
> I am adding a cast and moving along. I do wonder if gcc should be more
> consistent in how these types are defined but that would be harder to

That's a platform decision, not a gcc decision. AFAIK, there is no 
language requirement that wint_t and wchar_t be the same type.

> justify, fix, and test than it is probably worth.

Yes, definitely. It would be an ABI-breaking change for that platform.

>
> Thanks.
>> Cheers,
>>
>> Jon
>>
>>> }
>>> =================
>>>
>

-- 
Jon Roelofs
jonathan@codesourcery.com
CodeSourcery / Mentor Embedded



More information about the Newlib mailing list