• Problem with ranks

    From Spiros Bousbouras@21:1/5 to All on Sat May 30 01:55:46 2020
    Assume an implementation with 2 extended integer types as follows :

    - INT1 is signed , has 23 value bits and no corresponding unsigned type.
    - UINT1 is unsigned , has 40 value bits and no corresponding signed type.
    - Both have rank greater than int .
    - The rank of UINT1 is smaller than the rank of INT1 .

    The last stipulation is perverse but I don't see anything in "6.3.1.1
    Boolean, characters, and integers" which forbids it.

    With the above , if you have an addition where one operand is of type INT1
    and the other of type UINT1 then none of the possibilities (rules) in
    "6.3.1.8 Usual arithmetic conversions" after the part "Otherwise, the integer promotions are performed on both operands. Then the following rules are
    applied to the promoted operands:" is applicable. This even if we assume that ranks are always comparable which isn't clear.

    So I think that the following rule should be added to 6.3.1.1 :

    The rank of an integer type shall be greater or equal than the rank of any
    integer type with less or equal precision.

    --
    vlaho.ninja/prog

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Spiros Bousbouras on Sat May 30 02:48:13 2020
    On 5/29/20 9:55 PM, Spiros Bousbouras wrote:
    Assume an implementation with 2 extended integer types as follows :

    I suspect that you don't mean the following type names to be interpreted literally, but it would have been better for you to choose identifiers
    for those types which are reserved to the implementation, such as
    __int24_t and __uint40_t.

    - INT1 is signed , has 23 value bits and no corresponding unsigned type.

    "The standard and extended signed integer types are collectively called
    signed integer types." (6.2.5p4).
    "For each of the signed integer types, there is a corresponding (but
    different) unsigned integer type ..." (6.2.5p6).

    - UINT1 is unsigned , has 40 value bits and no corresponding signed type.

    That, however, is permitted, since 6.2.5p6 is asymmetrical.

    - Both have rank greater than int .
    - The rank of UINT1 is smaller than the rank of INT1 .

    The last stipulation is perverse but I don't see anything in "6.3.1.1 Boolean, characters, and integers" which forbids it.

    I believe you are correct about that, and I agree that it's a problem -
    but not because of what you wrote below:

    With the above , if you have an addition where one operand is of type INT1 and the other of type UINT1 then none of the possibilities (rules) in "6.3.1.8 Usual arithmetic conversions" after the part "Otherwise, the integer
    promotions are performed on both operands. Then the following rules are applied to the promoted operands:" is applicable.

    Since there is required to be a corresponding unsigned integer type, the
    last rule would apply:

    "Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type."

    That rule specifies a conversion that would loose information from the
    signed value, which is what I consider to be bad about the fact that
    such an implementation is allowed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Spiros Bousbouras on Sat May 30 02:11:57 2020
    Spiros Bousbouras <spibou@gmail.com> writes:

    Assume an implementation with 2 extended integer types as follows :

    - INT1 is signed , has 23 value bits and no corresponding unsigned type.
    - UINT1 is unsigned , has 40 value bits and no corresponding signed type.
    - Both have rank greater than int .
    - The rank of UINT1 is smaller than the rank of INT1 .

    Neither of these types is allowed. Except for _Bool, all integer
    types have a corresponding type of opposite signedness.

    The last stipulation is perverse but I don't see anything in "6.3.1.1 Boolean, characters, and integers" which forbids it.

    In reading the C standard it's important to read widely. In
    this case the provisions you're missing may be found in
    section 6.2.5 paragraphs 4 through 9.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to James Kuyper on Sat May 30 02:18:37 2020
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    On 5/29/20 9:55 PM, Spiros Bousbouras wrote:

    Assume an implementation with 2 extended integer types as follows :

    I suspect that you don't mean the following type names to be interpreted literally, but it would have been better for you to choose identifiers
    for those types which are reserved to the implementation, such as
    __int24_t and __uint40_t.

    - INT1 is signed , has 23 value bits and no corresponding unsigned type.

    "The standard and extended signed integer types are collectively called signed integer types." (6.2.5p4).
    "For each of the signed integer types, there is a corresponding (but different) unsigned integer type ..." (6.2.5p6).

    - UINT1 is unsigned , has 40 value bits and no corresponding signed type.

    That, however, is permitted, since 6.2.5p6 is asymmetrical.

    No, it isn't. Read 6.2.5 p6 more carefully. Not counting _Bool,
    the only types that are unsigned integer types each corresponds
    to a signed integer type. If a type doesn't have a corresponding
    signed integer type, it isn't an unsigned integer type (unless
    of course it is _Bool).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to James Kuyper on Sat May 30 09:04:51 2020
    On 5/30/20 2:48 AM, James Kuyper wrote:
    On 5/29/20 9:55 PM, Spiros Bousbouras wrote:
    Assume an implementation with 2 extended integer types as follows :

    I suspect that you don't mean the following type names to be interpreted literally, but it would have been better for you to choose identifiers
    for those types which are reserved to the implementation, such as
    __int24_t and __uint40_t.

    - INT1 is signed , has 23 value bits and no corresponding unsigned type.

    "The standard and extended signed integer types are collectively called signed integer types." (6.2.5p4).
    "For each of the signed integer types, there is a corresponding (but different) unsigned integer type ..." (6.2.5p6).

    There's an additional requirement which wasn't relevant to what I said
    last night, but is relevant to my corrections below: "... that uses the
    same amount of storage. ...". I get the impression that you chose 23
    bits to fit in 3 8-bit bytes, and 40 bits to fit in 5 8-bit bytes. If
    so, then the corresponding unsigned type can have at most 24 bits.

    - UINT1 is unsigned , has 40 value bits and no corresponding signed type.

    That, however, is permitted, since 6.2.5p6 is asymmetrical.

    - Both have rank greater than int .
    - The rank of UINT1 is smaller than the rank of INT1 .

    The last stipulation is perverse but I don't see anything in "6.3.1.1
    Boolean, characters, and integers" which forbids it.

    I believe you are correct about that, and I agree that it's a problem -
    but not because of what you wrote below:

    That didn't seem right to me. I was sure there was a relevant clause prohibiting it. However, I couldn't find it, so I assumed I might have
    been remembering incorrectly. The problem was that I was assuming it
    should be somewhere under 6.3.1.1, whereas it's actually in 6.2.5p8:

    "For any two integer types with the same signedness and different
    integer conversion rank (see 6.3.1.1), the range of values of the type
    with smaller integer conversion rank is a subrange of the values of the
    other type."

    I must have been up too late last night - a search I remember performing
    should have turned up that clause. My wife and I are luckily both able
    to continue telecommuting full-time during this pandemic, but the twins' preschool is closed. Finding enough time to get everything done has been difficult.

    Since there is required to be an unsigned integer type corresponding to
    INT1, then if that type has only 24 bits, it must have a rank lower than
    that of UINT1.

    "The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any." (6.3.1.1p1).

    Therefore, the rank of INT1 must be the same as the rank of its
    corresponding unsigned type, and therefore must be less than the rank of
    UINT1.

    There is a way around this - you could have sizeof(INT1) = 6, with 24
    padding bits - quite perverse, but permitted by the standard. The
    corresponding unsigned type could then have 48 value bits, in which case
    their shared rank would have to be greater than UINT1.

    With the above , if you have an addition where one operand is of type INT1 >> and the other of type UINT1 then none of the possibilities (rules) in
    "6.3.1.8 Usual arithmetic conversions" after the part "Otherwise, the integer
    promotions are performed on both operands. Then the following rules are
    applied to the promoted operands:" is applicable.

    Since there is required to be a corresponding unsigned integer type, the
    last rule would apply:

    "Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type."

    That rule specifies a conversion that would loose information from the
    signed value, which is what I consider to be bad about the fact that
    such an implementation is allowed.

    You can still get into this situation with my 48 bit scenario, but it's
    no longer problematic, since in that case the corresponding unsigned
    type is big enough that no information will be lost.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jameskuyper@alumni.caltech.edu@21:1/5 to Tim Rentsch on Sat May 30 07:11:07 2020
    On Saturday, May 30, 2020 at 5:18:39 AM UTC-4, Tim Rentsch wrote:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    On 5/29/20 9:55 PM, Spiros Bousbouras wrote:
    ...
    - UINT1 is unsigned , has 40 value bits and no corresponding signed type.

    That, however, is permitted, since 6.2.5p6 is asymmetrical.

    No, it isn't. Read 6.2.5 p6 more carefully. ...

    You're right. While the part that I quoted is asymmetrical, the last
    part of that clause says:

    "The type _Bool and the unsigned integer types that correspond to the
    standard signed integer types are the _standard unsigned integer types_.
    The unsigned integer types that correspond to the extended signed
    integer types are the _extended unsigned integer types_. The standard
    and extended unsigned integer types are collectively called _unsigned
    integer types_."

    I've used '_' to mark the phrases that are in italics, indicating that
    the sentences containing those phrases constitute the official
    definitions of those terms. Therefore, you are correct - UINT1 wouldn't
    qualify as an unsigned integer type, because it doesn't correspond to
    any signed integer type.

    I'd much prefer, in the future, if you would simply quote the relevant
    text, rather than asking me to "Read ... more carefully." Based on
    previous experience with you, there's a pretty good chance that I won't recognize the text that you think is relevant, because in my opinion, it
    isn't relevant, though this particular case is not an example.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to jameskuyper@alumni.caltech.edu on Sun Jun 28 05:54:17 2020
    jameskuyper@alumni.caltech.edu writes:

    On Saturday, May 30, 2020 at 5:18:39 AM UTC-4, Tim Rentsch wrote:

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    On 5/29/20 9:55 PM, Spiros Bousbouras wrote:

    ...

    - UINT1 is unsigned , has 40 value bits and no corresponding signed type. >>>
    That, however, is permitted, since 6.2.5p6 is asymmetrical.

    No, it isn't. Read 6.2.5 p6 more carefully. ...

    You're right. While the part that I quoted is asymmetrical, the last
    part of that clause says:

    "The type _Bool and the unsigned integer types that correspond to the standard signed integer types are the _standard unsigned integer types_.
    The unsigned integer types that correspond to the extended signed
    integer types are the _extended unsigned integer types_. The standard
    and extended unsigned integer types are collectively called _unsigned
    integer types_."

    I've used '_' to mark the phrases that are in italics, indicating that
    the sentences containing those phrases constitute the official
    definitions of those terms. Therefore, you are correct - UINT1 wouldn't qualify as an unsigned integer type, because it doesn't correspond to
    any signed integer type.

    I'd much prefer, in the future, if you would simply quote the relevant
    text, rather than asking me to "Read ... more carefully." Based on
    previous experience with you, there's a pretty good chance that I won't recognize the text that you think is relevant, because in my opinion, it isn't relevant, though this particular case is not an example.

    What I would like is a response more along these lines: "Yes I
    think I see what you're getting at. That conclusion seems right
    to me. Thank you for the followup." Not necessarily those
    words exactly of course but as a fuzzy outline of a suggestion.

    After there is some indication that you are trying to pay more
    attention to what's important to me, I may be more receptive to
    your requests about what is important to you.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)