Re: Casting an array to integer type



Eric Sosman <eric.sosman@xxxxxxx> writes:

> tedu wrote:
> > Eric Sosman wrote:
> >
> >> struct { int flag : 1; } s;
> >>
> >>... the value of `s.flag' will always be zero, no matter what
> >>you try to assign to it. (Explanation: if `int' is signed
> >>when used as a bit-field base, the lone bit of `s.flag' will
> >>be its sign bit and there will be no value bits at all.)
> >
> >
> > I may be misunderstanding how bitfields work, but why couldn't you read
> > and write the sign bit in such a case?
>
> The Standard allows three representations for signed
> integers: signed magnitude, ones' complement, and two's
> complement. In all three, if the sign bit is clear the
> value is what you'd expect by considering the value bits
> as ordinary binary notation. Since s.flag has no value
> bits, its value when the sign bit is clear must be zero.
>
> Now for the negatives. If the sign bit is set
>
> - for signed magnitude, the value is the negative of
> the number obtained from the value bits. The value
> bits contribute zero, which when negated is still
> zero.[*]
>
> - for ones' complement, the value is the negative of
> the number obtained by inverting all the value bits.
> There are no value bits to invert, so the zero value
> they contribute is still zero after negation.[*]
>
> - for two's complement, the value is the number obtained
> from the value bits, minus 2**k where k is the count
> of value bits (zero in this case). The value bits
> produce a zero, and subtracting 2**0 == -1 yields -1.
> Aha! I see that I mis-remembered and mis-stated
> the case.
>
> So: in two of the allowable representations the value
> is uniformly zero.[*] In two's complement the value is
> either zero or minus one, but never plus one. When I said
> `if (s.flag)' could not succeed I was wrong (for the common
> case of two's complement); what I should have said had I
> remembered the case better and/or been thinking more clearly
> is that `if (s.flag > 0)' or `if (s.flag == 1)' could never
> succeed, not in any of the three representations. And indeed,
> this is what the compiler warned about: the range of s.flag
> includes no positive values, so the compiler emitted the same
> warning it would for `if (sizeof(int) < 0)'. I apologize if
> I've misled anyone.
>
> [*] The Standard permits minus zero to be a "trap value,"
> meaning that you don't even get a value at all: you get a
> signal of some kind instead. In all three representations
> s.flag = 1 is dubious, because 1 is outside the representable
> range: you'll get an implementation-defined value or an
> implementation-defined signal.

Actually, 'if (s.flag > 0)' or 'if (s.flag == 1)' could
succeed, in any of the three representation schemes,
depending on the implementation.

The rule about conversions that's indirectly referenced in
the *'ed paragraph is slightly misquoted. The wording in
6.3.1.3 p3 says the result is implementation-defined, not
that the conversions yields an implementation-defined value:

6.3.1.3

3 Otherwise, the new type is signed and the value
cannot be represented in it; either the result is
implementation-defined or an implementation-defined
signal is raised.

Because the result is implementation-defined, it can be a
trap representation. A sign bit of 1, with no value bits,
can be (implementation-)defined to be a trap representation
in any of the three representation schemes (6.2.6.2 p2). If
the result of the conversion is a trap representation, the
expressions accessing s.flag are undefined behavior; so,
they might yield 1 as a result.

The question of what conversions happen when assigning to
the bitfield s.flag is a little murky, because exactly what
the type is of a bitfield is a little murky. However, one
of three cases holds: (1) a conversion to the narrow type
happens because of the assignment -- this conversion can
yield a trap representation and so produces undefined
behavior; (2) a conversion to the narrow type happens when
the value of the right hand side is stored, which again can
yield a trap representation and produce undefined behavior;
or, (3) the right hand side is converted to 'int' type, and
there is no conversion to the narrow type, but storing the
value into the too-narrow bitfield results in an exceptional
condition, again producing undefined behavior. In each case
the result of the undefined behavior could cause the
expressions referencing s.flag to have the value 1.

The s.flag expressions could also yield the value 1 without
the presence of undefined behavior. The reason is that it's
implementation-defined whether 'int' on a bitfield is the
same as 'signed int' or 'unsigned int' (6.7.2 p5).
.



Relevant Pages

  • Re: newbie - integer variable with leading zero for os.makedirs
    ... >string from ascii to integer, but loses the first zero padding. ... The same binary number (judging by the decimal representation (488) that's being printed). ... as '750' so the conversion from string to binary integer succeeds and gives the value 750. ...
    (comp.lang.python)
  • Re: C++ Command Line data
    ... > an error and a valid conversion of the value zero. ... which formally has Undefined Behavior for a range error. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Adding Older Versions of GCC To The Tool Chain ... safely?!?!
    ... There is by definition no such thing as 'an unsigned overflow', ... the bits of the object representation ... for conversion to an unsigned type to be performed on mathematical ... If an exceptional condition occurs during the evaluation of an ...
    (comp.os.linux.development.apps)
  • Re: Simple subtraction formula returning strange results = Excel g
    ... subtraction differ only in some number of the least significant bits ... The 64-bit floating-point representation is shown in the stylized hex form &hEEEMMMMM,M...M, where "E" is the biased exponent and "M" is the mantissa. ... always results in a zero in A3. ... A1 displays as 1.79769313486232E+308, but the first 30 digits of its exact representation are 179769313486231,57081452742373. ...
    (microsoft.public.excel.worksheet.functions)
  • Re: Question re. integral promotion, signed->unsigned
    ... >>Why is it OK to reinterpret a signed integral type as ... > but such a conversion isn't well defined if the value of the unsigned ... regardless of the representation of negative values. ... > While this conversion is well defined and yields the same result, ...
    (comp.lang.c)