[Bug c/39170] cannot silence -Wconversion warnings for bit-fields

2010-02-18 Thread Zachary_Deretsky at mentor dot com


--- Comment #8 from Zachary_Deretsky at mentor dot com  2010-02-18 20:50 
---
With -Wconversion for the assignment to bitfields gcc 4.4.2 gives a
warning, which is impossible to fix.

This BUG (I hope everybody agrees it is a BUG) gives us a lot of
trouble while porting our code (45 developers, 7 year history) from
4.2.4 to 4.4.2

We spent a lot of effort to make our code clean with 
-Wshadow -Wconversion -Wall -Werror flags and now our only choice is
to remove -Wconversion.

Please assign and fix this ASAP.

Thank you, Zach.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39170



[Bug c/39170] cannot silence -Wconversion warnings for bit-fields

2010-03-05 Thread Zachary_Deretsky at mentor dot com


--- Comment #9 from Zachary_Deretsky at mentor dot com  2010-03-06 00:20 
---
I was wrong, the warning is correct and there is a way to fix it.

***1. The easy recipe: For the assignment to bit-fileds use unsigned int
bit-field on the left and mask the right side with the appropriate mask.

***2. Explanation given by Alexander Smundak from Cisco:
Actually, the compiler is doing the right thing. Let's simplify it:
--
struct data_t {
int bit:1;
} data;

void foo() {
data.bit = 1;
}
-
$ gcc.c4.4.0-p0 -fsyntax-only -Wall -Wconversion wbit.cpp
wbit.cpp: In function ‘void foo()’:
wbit.cpp:6: warning: conversion to ‘signed char:1’ alters ‘int’ constant value

`int' is signed, meaning that the highest bit of data.bit is to be extended
when moved to a longer integer. Which means that the values for the 1-bit sized
integer are 0 and -1. Indeed, if I change the assignment above to 
data.bit = -1;
the code will compile without warnings. And indeed that's what happens.
Likewise, for the 2-bit bit fields the possible values are
0,1,-1 and -2. Etc.

***3. Here is a little code example to try with g++ -Wconversion b.cpp

-
// b.cpp
#define M23 ((1 << 23) - 1)
#define M24 ((1 << 24) - 1)


class xxx {
public:
  xxx():u_24(0), i_24(0) {}
  unsigned int u_24:24;
  int i_24:24;
};

int main(int argc, char** argv) {
  xxx x;
  unsigned int y = 0x;
  x.u_24 = M24 & y;
  x.i_24 = M23 & y;
  x.i_24 = M24 & y; // warning: conversion to  int:24  from  int  may alter its
value
}
-

Thanks, Zach.


-- 

Zachary_Deretsky at mentor dot com changed:

   What|Removed |Added

     CC|        |Zachary_Deretsky at mentor
           ||dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39170