bug ? : -Wpedantic -Wconversion 'short a=1; a-=1;' complaint
Jason Vas Dias
jason.vas.dias@gmail.com
Wed May 16 13:58:00 GMT 2018
Great thanks for your informative response, Jim! :
RE:
On 23/04/2018, Jim Wilson <jimw@sifive.com> wrote:
> On 04/23/2018 07:11 AM, Jason Vas Dias wrote:
>>
>> I really do not think a '-Wpedantic -Wconversion' warning should
>> be generated for the following code, but it is
>> (with GCC 6.4.1 and 7.3.1 on RHEL-7.5 Linux) :
>>
>> $ echo '
>> typedef unsigned short U16_t;
>> static void f(void)
>> { U16_t a = 1;
>> a-=1;
>> }' > t.C;
>
> gcc@gcc.gnu.org dropped as inappropriate. Note that gcc-bugs is output
> from our bugzilla. Sending email here isn't very useful. If you want a
> bug fixed, you have to open a bug report in bugzilla. You can ask gcc
> questions on gcc help.
>
> In the C language, operations on short and always performed as int, and
> then converted back to short. Subtracting one may generated a negative
> number, which converted to unsigned short will change its value. So the
> warning seems appropriate.
>
> Note that -Wconversion means different things in different gcc versions.
> It current meaning is to warn for any implicit cast that may change a
> value. This is not very useful in general, and is not an option that I
> would recommend using by default. In old gcc versions, -Wconversion
> warned for code that had different meaning in K&R C and ISO C. That was
> useful, and some people used that option by default, but the option no
> longer does that.
>
> You can silence the warning by adding an explicit cast.
> a = (U16_t) (a - 1);
>
> Jim
>
But I still think, in modern GCC, the behaviour of this warning option is a bug.
When I look at the code generated for the above example, I can see
the compiler is actually generating 16-bit operations:
$ gcc -std=c11 -Wall -Wextra -pedantic -Wconversion -S -o u16.s u16.c
u16.c: In function ‘f’:
u16.c:9:6: warning: conversion to ‘U16_t {aka short unsigned int}’
from ‘int’ may alter its value [-Wconversion]
v-=1;
^
But looking at the assembler generated :
movw $1, -2(%rbp)
subw $1, -2(%rbp)
we see that on x86_64 at least, the compiler is actually generating
16-bit operations on two-byte values.
I can understand that on architectures such as ARM , it might be
appropriate to generate the warning, because on that platform,
a 32-bit operation may actually be generated for the code.
But if no 32-bit operation is being generated, why issue the warning?
So it is not the case that
> In the C language, operations on short are always performed as int, and
> then converted back to short .
That may have been true with ANSI C90, but not with more recent versions
of the C language; surely GCC should know what standard & CPU it is generating
code for, and emit appropriate warnings for that standard and CPU ?
And your suggested fix illustrates my point about the warning encouraging
unnecessary casts:
> You can silence the warning by adding an explicit cast.
> a = (U16_t) (a - 1);
Actually, in this case, gcc is clever enough to realize that a cast is
not required,
and actually generates identical code with or without the cast:
movw $1, -2(%rbp)
subw $1, -2(%rbp)
But C++ programmers are encouraged to look at any C-style "(X)y" cast as
"Create an anonymous Temporary to hold y cast to type X " .
Even though that is not what is going on here, I think the warning does
not help programmers understand what code is being generated
(the 16-bit operations) and incorrectly makes them think a 32-bit
temporary is being generated.
So I think that '-Wconversion' should have no effect if '-pedantic'
is in effect,
because that combination produces erroneous and misleading warnings .
Thanks & Best Regards,
Jason
More information about the Gcc-bugs
mailing list