Undefined Behavior. ..

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jameskuyper

    #31
    Re: Undefined Behavior. ..



    Tim Rentsch wrote:
    James Kuyper <jameskuyper@ve rizon.netwrites :
    >
    [...]

    The standard explicitly states (6.2.6.2p2) that any given signed integer
    type has one bit pattern that might or might not be a trap
    representation - it's up to the implementation to decide (and to
    document their decision). For types that use a one's complement or
    sign-magnitude representation, this is the bit pattern that would
    otherwise represent negative 0. If the type uses a twos-complement
    representation, this is the bit pattern that would otherwise represent
    -2^N, where N is the number of value bits in the type.

    Some people read that clause as allowing only that one trap
    representation, and requiring that all other bit patterns must be valid.
    I don't read it that way. It seems to me that what it says still allows
    for the possibility of other trap representations as well. An
    implementation that used 1 padding bit, 1 sign bit, and 30 value bits
    for 'int' could set INT_MAX to 1000000000, and INT_MIN to -1000000000,
    and declare that all bit patterns that would seem to represent values
    outside that range are actually trap representations . It's been argued
    that this violates the requirement that for any signed type "Each bit
    that is a value bit shall have the same value as the same bit in the
    object representation of the corresponding unsigned type." But every
    does have that value, in every non-trap representation that has that bit
    set.
    >
    I must admit to having trouble with this one. What's the basis for
    the position you state? In the example given the presence of a
    padding bit seems completely irrelevant (except perhaps to make the
    number of bits a multiple of 8 while preserving round limits?)
    Exactly - it serves to make an extremely implausible but legal
    implementation very marginally more plausible.
    -- is
    there any difference between this example and one using 31 value bits
    to represent values in [-2000000000 .. 2000000000]?
    Yes - I can imagine reasons for wanting INT_MAX to be a power of 10; I
    find it much harder to come up with reasons for wanting INT_MAX to be
    2 times a power of 10. Again, it's just a matter of making an
    intrinsically implausible implementation a little more plausible.
    ... It seems like
    all you are saying is that you think some combinations of values
    bits are allowed to be trap representations whereas other people
    think they aren't (not counting the distinguished ones explicitly
    identified in the Standard, of course). What's the argument to
    support this position?
    Which position - mine or theirs? My position is based upon the fact
    that the standard explicitly allows for trap representations , and says
    nothing to limit how many any given type may have. The opposing
    position is based upon the claim that 6.2.6.2p2 defines the only trap
    representation involving value bits that a signed integer type is
    allowed to have. As I read it, 6.2.6.2p2 serves primarily to explain
    the fact that the bit pattern that would otherwise represent negative
    zero in 1's complement or sign-magnitude representations is allowed to
    be a trap representation. This clears up any ambiguity that might
    arise due to the fact that 0 has two distinct representations for such
    types. It doesn't imply in any way that negative zero is the only
    allowed trap representation. The fact that it also defines a bit
    pattern for 2's complement representations that is allowed to be a
    trap representation is a weak point in my argument. If my argument is
    correct, that clause is redundant; but it doesn't directly contradict
    my conclusion.

    Comment

    • Gordon Burditt

      #32
      Re: Undefined Behavior. ..

      >I had to read this a couple of times before I understood the main
      >point. I mostly agree with the main point (explained further below),
      >but the inference stated in the first sentence seems wrong to me.
      >It's true that undefined behavior during, e.g., macro processing might
      >cause compilation to fail, but execution-time undefined behavior can't
      >start until program execution is started. Whatever execution-time
      >undefined behavior there might be isn't allowed to creep across the
      >boundary into program translation.
      Get a good textbook on Temporal Mechanics. Miles O'Brien of Deep
      Space Nine has one. The subject isn't as simple as you might think.

      One call to fflush(stdin) retroactively removed the 'ant' keyword
      from C89 (const ant int xyz = 42; defined an actual integer constant
      expression in a variable). Too bad; it was a useful feature :-) .


      Comment

      • Tim Rentsch

        #33
        Re: Undefined Behavior. ..

        gordon@hammy.bu rditt.org (Gordon Burditt) writes:
        I had to read this a couple of times before I understood the main
        point. I mostly agree with the main point (explained further below),
        but the inference stated in the first sentence seems wrong to me.
        It's true that undefined behavior during, e.g., macro processing might
        cause compilation to fail, but execution-time undefined behavior can't
        start until program execution is started. Whatever execution-time
        undefined behavior there might be isn't allowed to creep across the
        boundary into program translation.
        >
        Get a good textbook on Temporal Mechanics. Miles O'Brien of Deep
        Space Nine has one. The subject isn't as simple as you might think.
        I already have one. It was required reading in the Temporal Mechanics
        course that I took ten years from now.

        Comment

        • Tim Rentsch

          #34
          Re: Undefined Behavior. ..

          jameskuyper <jameskuyper@ve rizon.netwrites :
          Tim Rentsch wrote:
          James Kuyper <jameskuyper@ve rizon.netwrites :
          [...]
          >
          The standard explicitly states (6.2.6.2p2) that any given signed integer
          type has one bit pattern that might or might not be a trap
          representation - it's up to the implementation to decide (and to
          document their decision). For types that use a one's complement or
          sign-magnitude representation, this is the bit pattern that would
          otherwise represent negative 0. If the type uses a twos-complement
          representation, this is the bit pattern that would otherwise represent
          -2^N, where N is the number of value bits in the type.
          >
          Some people read that clause as allowing only that one trap
          representation, and requiring that all other bit patterns must be valid.
          I don't read it that way. It seems to me that what it says still allows
          for the possibility of other trap representations as well. An
          implementation that used 1 padding bit, 1 sign bit, and 30 value bits
          for 'int' could set INT_MAX to 1000000000, and INT_MIN to -1000000000,
          and declare that all bit patterns that would seem to represent values
          outside that range are actually trap representations . It's been argued
          that this violates the requirement that for any signed type "Each bit
          that is a value bit shall have the same value as the same bit in the
          object representation of the corresponding unsigned type." But every
          does have that value, in every non-trap representation that has that bit
          set.
          I must admit to having trouble with this one. What's the basis for
          the position you state? In the example given the presence of a
          padding bit seems completely irrelevant (except perhaps to make the
          number of bits a multiple of 8 while preserving round limits?)
          >
          [..minor detour on padding bits..]
          >
          ... It seems like
          all you are saying is that you think some combinations of values
          bits are allowed to be trap representations whereas other people
          think they aren't (not counting the distinguished ones explicitly
          identified in the Standard, of course). What's the argument to
          support this position?
          >
          Which position - mine or theirs? My position is based upon the fact
          that the standard explicitly allows for trap representations , and says
          nothing to limit how many any given type may have. The opposing
          position is based upon the claim that 6.2.6.2p2 defines the only trap
          representation involving value bits that a signed integer type is
          allowed to have. As I read it, 6.2.6.2p2 serves primarily to explain
          the fact that the bit pattern that would otherwise represent negative
          zero in 1's complement or sign-magnitude representations is allowed to
          be a trap representation. This clears up any ambiguity that might
          arise due to the fact that 0 has two distinct representations for such
          types. It doesn't imply in any way that negative zero is the only
          allowed trap representation. The fact that it also defines a bit
          pattern for 2's complement representations that is allowed to be a
          trap representation is a weak point in my argument. If my argument is
          correct, that clause is redundant; but it doesn't directly contradict
          my conclusion.
          So if I may paraphrase/summarize your argument, you're saying that
          trap representations involving some combination of value bits
          aren't explicitly forbidden, and therefore they are allowed.
          Is that right?

          If that's what you're saying, I agree that TR aren't explicitly
          forbidden, in the sense that there is no statement in the standard
          that says directly that other combinations of value bits may not be
          TR. However, I think this requirement is given implicitly by how
          integer values are represented, specifically in the definition of
          value bits. For unsigned types, from 6.2.6.2p1:

          If there are N value bits, each bit shall represent a
          different power of 2 between 1 and 2**(N-1)

          And for signed types, from 6.2.6.2 p 3:

          Each bit that is a value bit shall have the same value as the same
          bit in the object representation of the corresponding unsigned
          type (if there are M value bits in the signed type and N in the
          unsigned type, then M<=N).

          The statements seem specific enough so that TR involving combinations
          of value bits aren't allowed, except by explicit exception, which
          explains why the three distinguished representations are identified
          specifically as possibly being TR. I agree that those representations
          being associated with negative zero (in two cases) muddies the point;
          however, I think that's incidental, since some implementations support
          negative zero, and there is some other text discussing negative zeros
          that specifically are not TR. Of course I agree with your point that
          the TR for 2's complement weakens the case that other TR are allowed.

          If we look for corroborating evidence, think about this. If what
          you're saying is right, then bitfields should also be allowed TR
          (besides the distinguished three) as part of their value bit range.
          In fact, since there aren't any limits set on what values signed
          bitfields must represent (with 0 as a possible exception, for example
          in (signed _Bool)), signed bitfields couldn't be used portably at
          all (not counting the trivial case where they only ever have the
          value 0). There is support for the proposition that bitfields
          may not have TR in 6.7.7p6:

          EXAMPLE 3 The following obscure constructions

          typedef signed int t;
          typedef int plain;
          struct tag {
          unsigned t:4;
          const t:5;
          plain r:5;
          };

          declare a typedef name t with type signed int, a typedef name
          plain with type int, and a structure with three bit-field
          members, one named t that contains values in the range [0, 15],
          an unnamed const-qualified bit-field which (if it could be
          accessed) would contain values in either the range [-15, +15] or
          [-16, +15], and one named r that contains values in one of the
          ranges [0, 31], [-15, +15], or [-16, +15]. (The choice of range
          is implementation-defined.)

          The numeric ranges given indicate pretty clearly that bitfields may
          not have TR in their usual value range. Unless there is other text
          that differentiates bitfields and non-bitfield integer types with
          respect to TR (and I haven't been able to find any), this evidence
          indicates pretty strongly that TR are not allowed in the usual
          value range for integer types.

          Comment

          Working...