This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Help with bit-field semantics in C and C++
- From: Joe Buck <Joe dot Buck at synopsys dot COM>
- To: Dave Korn <dk at artimi dot com>
- Cc: "'Mark Mitchell'" <mark at codesourcery dot com>,"'Gabriel Dos Reis'" <gdr at integrable-solutions dot net>,"'David Carlton'" <david dot carlton at sun dot com>,"'Mike Stump'" <mrs at apple dot com>, "'Roger Sayle'" <roger at eyesopen dot com>,gcc at gcc dot gnu dot org
- Date: Wed, 25 Aug 2004 10:01:44 -0700
- Subject: Re: Help with bit-field semantics in C and C++
- References: <20040824153107.A16358@synopsys.com> <NUTMEGjQaNT9ldvyr1U00000f4d@NUTMEG.CAM.ARTIMI.COM>
On Wed, Aug 25, 2004 at 12:26:24PM +0100, Dave Korn wrote:
> It seems to me that "unspecified" and "undefined" are repeatedly being
> confused in this discussion. They are both clearly defined technical terms
> in the standard; they have different meanings; everyone participating in
> this thread should make very sure they know which one they're referring to
> at any time.
>
> "undefined" is the one that covers rm -rf'ing your hard drive.
>
> "unspecified" is what the standard says that the result of the truncating
> cast we've been discussing is. That means (IIUIC) that the result has to be
> one of the enumeration values, but that the standard does not specify which
> _particular_ one.
If you are correct, then it appears that every C++ compiler I know of gets
this wrong. That is, it seems that every C++ compiler happily allows
out-of-range integers to be assigned to enums, and does so in a way that
the effect is observable.
If your interpretation is correct, then I can write the following test for
a conforming compiler; g++ fails this test. I'm deliberately putting
is_zero and is_one in separate functions, to catch a compiler that might
allow storing the 3, but that would later assume that global must be zero
or one and optimize the "if" away.
-------------------------------------------------------------------
extern "C" void abort();
enum E { zero, one };
E global;
void assign_global(int arg) {
global = (E)arg;
}
bool is_zero() {
return global == zero;
}
bool is_one() {
return global == one;
}
int main(int,char**) {
assign_global(3);
if (!is_zero() && !is_one())
abort();
}