Great thanks for your informative response, Jim! : RE: On 23/04/2018, Jim Wilson <j...@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; > > g...@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