Given the code below, gcc emits the following error: error: attempt to take address of bit-field structure member 'MyClass::field1' This compiles fine with Sun's CC, IBM's xlC, and Comeau. The C++ 2003 standard mentions in 9.6p2 that a non-const reference can't be bound to a bit field, but that a const reference can be (although it's actually bound to a temporary initialized with a copy of the bit field rather than the field itself) so I expect the below code to work fine. // Code class MyClass { public: MyClass() { field1 = 0; }; int field1 : 4; }; int main() { MyClass myClass; const int &fieldRef1 = myClass.field1; return 0; }
Confirmed. Note that the frontend would need to make sure to unfold the reference for the middle-end - the middle-end can't bear taking the address of a bitfield.
Wow, taking the address of a bit field. That can only be C++. This should be closed as a dup of bug 5... Oh, well... :-)
Why C++0x?!?
Noone's taking the address of a bitfield, the stnadard specifically says "The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields." What happens is the same as: double d = 0; const int& i = d; a temporary is created and the reference bound to it. And this definitely isn't new in C++0x! The reference for C++03 should be 9.6p3 rather than p2
Long-standing bug.
Here's a quick hack that causes a temporary to be generated when binding a bit-field to a reference-to-const. $ svn diff Index: call.c =================================================================== --- call.c (revision 173769) +++ call.c (working copy) @@ -8594,7 +8594,7 @@ expr = error_mark_node; else { - if (!lvalue_or_rvalue_with_address_p (expr)) + if (is_bitfield_expr_with_lowered_type (expr) || !lvalue_or_rvalue_with_address_p (expr)) { tree init; var = set_up_extended_ref_temp (decl, expr, cleanup, &init); I'll try to make time to clean that up and add regression tests before running it by someone with stronger gcc-fu.
Unsurprisingly the quick hack isn't really good enough -- it'll happily bind a non-const reference to a temporary initialized from a bitfield. (...and I guess that's why we have tests, and code reviews.)
Interestingly this works with Apple's g++ 4.2.1, specifically i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3), but not with their 4.0.1 release. Tested with: int main() { struct S { S(): i(0) {} int i : 3; }; S s; printf("&s: %p\n", (void*)&s); int const& cr(s.i); // should compile, binding to a temporary printf("&cr: %p\n", (void*)&cr); } A non-const reference still correctly gives an error: st.cc:12: error: invalid initialization of reference of type ‘int&’ from expression of type ‘signed char:3’
This is fixed in 4.7.0. I'm adding the testcase and closing the PR.
Author: paolo Date: Thu Oct 11 02:34:32 2012 New Revision: 192347 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=192347 Log: 2012-10-10 Paolo Carlini <paolo.carlini@oracle.com> PR c++/43663 * g++.dg/init/bitfield3.C: New. Added: trunk/gcc/testsuite/g++.dg/init/bitfield3.C Modified: trunk/gcc/testsuite/ChangeLog
Done.