From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10090 invoked by alias); 6 Mar 2010 00:20:20 -0000 Received: (qmail 9909 invoked by uid 48); 6 Mar 2010 00:20:09 -0000 Date: Sat, 06 Mar 2010 00:20:00 -0000 Message-ID: <20100306002009.9908.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug c/39170] cannot silence -Wconversion warnings for bit-fields In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "Zachary_Deretsky at mentor dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2010-03/txt/msg00514.txt.bz2 ------- 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 = 0xffff; 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