Negative values in unsigned int

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

    Negative values in unsigned int

    I wasn't able to find an answer to the following questions in a draft
    version of IOS 9899-99. What is the semantic when you decrement an
    unsigned int below 0 (or subtract two unsigned ints with negative
    result)? AFAIR, this results in implementation-defined behavior but
    not undefined behavior. Is that correct?

    So what does the standard say to this code?

    void f(void)
    {
    unsigned int n = 0;
    n--;
    }

    Also, do I have implementation-defined or undefined behavior, if I
    decrement below zero but don't use the value, as in the following
    code?

    void f(unsigned int n)
    {
    while (n-- 0) { /* In the last loop iteration, n is
    ; decremented from 0, but not used
    } afterwards */
    }

    A short notice with section number in the standard would be nice
    (as I think section numbering in my draft version is not that
    different).

    urs
  • viza

    #2
    Re: Negative values in unsigned int

    On Mon, 08 Sep 2008 14:38:16 +0200, Urs Thuermann wrote:
    So what does the standard say to this code?
    unsigned int n = 0;
    n--;
    Always results in UINT_MAX.
    Also, do I have implementation-defined or undefined behavior, if I
    decrement below zero but don't use the value, as in the following code?
    >
    void f(unsigned int n)
    {
    while (n-- 0) { /* In the last loop iteration, n is
    ; decremented from 0, but not used
    } afterwards */
    }
    This evaluates the greater-than with the original value of n, then
    decrements n. n is automatic so its value is lost when the function
    returns.

    Comment

    • jameskuyper@verizon.net

      #3
      Re: Negative values in unsigned int

      Urs Thuermann wrote:
      I wasn't able to find an answer to the following questions in a draft
      version of IOS 9899-99. What is the semantic when you decrement an
      unsigned int below 0 (or subtract two unsigned ints with negative
      result)? AFAIR, this results in implementation-defined behavior but
      not undefined behavior. Is that correct?
      No. It is standard-defined behavior. Section 6.2.5p9 says:

      "A computation involving unsigned operands can never overflow, because
      a result that cannot be represented by the resulting unsigned integer
      type is reduced modulo the number that is one greater than the largest
      value that can be represented by the resulting type."
      So what does the standard say to this code?
      >
      void f(void)
      {
      unsigned int n = 0;
      n--;
      At this point, the value of n must be UINT_MAX.
      }
      >
      Also, do I have implementation-defined or undefined behavior, if I
      decrement below zero but don't use the value, as in the following
      code?
      >
      void f(unsigned int n)
      {
      while (n-- 0) { /* In the last loop iteration, n is
      ; decremented from 0, but not used
      } afterwards */
      }
      Since the behavior is standard-defined, you don't have to worry about
      it; whether or not the resulting value gets used doesn't matter. If
      the behavior were undefined (as, for example, INT_MAX+1), then the
      fact that you didn't use the result still wouldn't protect your code,
      at least in principle. As a practical matter, since the value is not
      used, an optimizing compiler might remove the calculation that
      produced the value, reducing the opportunities for undesireable
      consequences - but you should never write code which relies upon this.

      Comment

      • CBFalconer

        #4
        Re: Negative values in unsigned int

        Urs Thuermann wrote:
        >
        I wasn't able to find an answer to the following questions in a
        draft version of IOS 9899-99. What is the semantic when you
        decrement an unsigned int below 0 (or subtract two unsigned ints
        with negative result)? AFAIR, this results in implementation-
        defined behavior but not undefined behavior. Is that correct?
        No. It is carefully defined. Unsigned quantities do arithmetic
        modulo the (maximum unsigned value + 1).

        --
        [mail]: Chuck F (cbfalconer at maineline dot net)
        [page]: <http://cbfalconer.home .att.net>
        Try the download section.

        Comment

        • Ben Bacarisse

          #5
          Re: Negative values in unsigned int

          Urs Thuermann <urs@isnogud.es cape.dewrites:
          I wasn't able to find an answer to the following questions in a draft
          version of IOS 9899-99.
          <snip>
          A short notice with section number in the standard would be nice
          (as I think section numbering in my draft version is not that
          different).
          Mostly answered except for this bit. The main rule at work is 6.3.1.3
          paragraph 2.

          --
          Ben.

          Comment

          • Eric Sosman

            #6
            Re: Negative values in unsigned int

            jameskuyper@ver izon.net wrote:
            Urs Thuermann wrote:
            >I wasn't able to find an answer to the following questions in a draft
            >version of IOS 9899-99. What is the semantic when you decrement an
            >unsigned int below 0 (or subtract two unsigned ints with negative
            >result)? AFAIR, this results in implementation-defined behavior but
            >not undefined behavior. Is that correct?
            >
            No.
            Yes.
            It is standard-defined behavior. Section 6.2.5p9 says:
            >
            "A computation involving unsigned operands can never overflow, because
            a result that cannot be represented by the resulting unsigned integer
            type is reduced modulo the number that is one greater than the largest
            value that can be represented by the resulting type."
            Note the part beginning "the largest value ...". That
            value is implementation-defined, hence the value of the
            result is implementation-defined.

            --
            Eric Sosman
            esosman@ieee-dot-org.invalid

            Comment

            • Barry Schwarz

              #7
              Re: Negative values in unsigned int

              On Sun, 14 Sep 2008 17:20:16 -0400, Eric Sosman
              <esosman@ieee-dot-org.invalidwrot e:
              >jameskuyper@ve rizon.net wrote:
              >Urs Thuermann wrote:
              >>I wasn't able to find an answer to the following questions in a draft
              >>version of IOS 9899-99. What is the semantic when you decrement an
              >>unsigned int below 0 (or subtract two unsigned ints with negative
              >>result)? AFAIR, this results in implementation-defined behavior but
              >>not undefined behavior. Is that correct?
              >>
              >No.
              >
              Yes.
              >
              >It is standard-defined behavior. Section 6.2.5p9 says:
              >>
              >"A computation involving unsigned operands can never overflow, because
              >a result that cannot be represented by the resulting unsigned integer
              >type is reduced modulo the number that is one greater than the largest
              >value that can be represented by the resulting type."
              >
              Note the part beginning "the largest value ...". That
              >value is implementation-defined, hence the value of the
              >result is implementation-defined.
              The value is implementation defined but the behavior is not. The
              behavior is defined as quoted. Your approach would also render the
              behavior of
              int x = '0' < '1';
              is also implementation defined since the values of '0' and '1' are
              implementation dependent.

              --
              Remove del for email

              Comment

              • James Kuyper

                #8
                Re: Negative values in unsigned int

                Eric Sosman wrote:
                jameskuyper@ver izon.net wrote:
                >Urs Thuermann wrote:
                >>I wasn't able to find an answer to the following questions in a draft
                >>version of IOS 9899-99. What is the semantic when you decrement an
                >>unsigned int below 0 (or subtract two unsigned ints with negative
                >>result)? AFAIR, this results in implementation-defined behavior but
                >>not undefined behavior. Is that correct?
                >>
                >No.
                >
                Yes.
                >
                >It is standard-defined behavior. Section 6.2.5p9 says:
                >>
                >"A computation involving unsigned operands can never overflow, because
                >a result that cannot be represented by the resulting unsigned integer
                >type is reduced modulo the number that is one greater than the largest
                >value that can be represented by the resulting type."
                >
                Note the part beginning "the largest value ...". That
                value is implementation-defined, hence the value of the
                result is implementation-defined.
                No, that's implementation-dependent result, but not
                implementation-defined behavior. The implementation gets to decide for
                each unsigned type what the value of TYPE_MAX is. Having made that
                decision, they get no additional freedom in the value that results from
                overflow or underflow for unsigned; there's a standard-defined
                relationship between the two values.

                Comment

                • CBFalconer

                  #9
                  Re: Negative values in unsigned int

                  Barry Schwarz wrote:
                  >
                  .... snip ...
                  >
                  The value is implementation defined but the behavior is not. The
                  behavior is defined as quoted. Your approach would also render
                  the behavior of
                  int x = '0' < '1';
                  is also implementation defined since the values of '0' and '1'
                  are implementation dependent.
                  However since '1' is known to have the value ('0' + 1) that x is
                  thoroughly defined. If you picked 'a' and 'b' I could agree.

                  --
                  [mail]: Chuck F (cbfalconer at maineline dot net)
                  [page]: <http://cbfalconer.home .att.net>
                  Try the download section.

                  Comment

                  • Urs Thuermann

                    #10
                    Re: Negative values in unsigned int

                    jameskuyper@ver izon.net writes:
                    No. It is standard-defined behavior. Section 6.2.5p9 says:
                    >
                    "A computation involving unsigned operands can never overflow, because
                    a result that cannot be represented by the resulting unsigned integer
                    type is reduced modulo the number that is one greater than the largest
                    value that can be represented by the resulting type."
                    OK, Thanx. I've read the 1989 edition of the standard 10 or so years
                    ago and I had in mind that this would result in implementation-defined
                    behavior, but I probably confused that with the signed integer case
                    (which also is not implementation-defined but undefined if I read the
                    the standard correctly).
                    void f(unsigned int n)
                    {
                    while (n-- 0) { /* In the last loop iteration, n is
                    ; decremented from 0, but not used
                    } afterwards */
                    }
                    >
                    Since the behavior is standard-defined, you don't have to worry about
                    it; whether or not the resulting value gets used doesn't matter. If
                    the behavior were undefined (as, for example, INT_MAX+1), then the
                    fact that you didn't use the result still wouldn't protect your code,
                    at least in principle.
                    Yes, that is what I assumed also.
                    As a practical matter, since the value is not used, an optimizing
                    compiler might remove the calculation that produced the value,
                    reducing the opportunities for undesireable consequences - but you
                    should never write code which relies upon this.
                    Yes, of course. I had a function which does somthing similar to

                    void f(int n)
                    {
                    while (--n >= 0)
                    do_something();
                    }

                    and I wanted to change the parameter n to unsigned int like this

                    void f(unsigned int n)
                    {
                    while (n-- 0)
                    do_something();
                    }

                    and then I wondered what happens when n is 0 in the last loop
                    iteration. But your answer did clarify this completely, thanks
                    again.

                    urs

                    Comment

                    • Barry Schwarz

                      #11
                      Re: Negative values in unsigned int

                      On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <urs@isnogud.es cape.de>
                      wrote:
                      >jameskuyper@ve rizon.net writes:
                      >
                      >No. It is standard-defined behavior. Section 6.2.5p9 says:
                      >>
                      >"A computation involving unsigned operands can never overflow, because
                      >a result that cannot be represented by the resulting unsigned integer
                      >type is reduced modulo the number that is one greater than the largest
                      >value that can be represented by the resulting type."
                      >
                      >OK, Thanx. I've read the 1989 edition of the standard 10 or so years
                      >ago and I had in mind that this would result in implementation-defined
                      >behavior, but I probably confused that with the signed integer case
                      >(which also is not implementation-defined but undefined if I read the
                      >the standard correctly).
                      It was in C89 but no longer in C99.

                      --
                      Remove del for email

                      Comment

                      • Keith Thompson

                        #12
                        Re: Negative values in unsigned int

                        Barry Schwarz <schwarzb@dqel. comwrites:
                        On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <urs@isnogud.es cape.de>
                        wrote:
                        >>jameskuyper@v erizon.net writes:
                        >>
                        >>No. It is standard-defined behavior. Section 6.2.5p9 says:
                        >>>
                        >>"A computation involving unsigned operands can never overflow, because
                        >>a result that cannot be represented by the resulting unsigned integer
                        >>type is reduced modulo the number that is one greater than the largest
                        >>value that can be represented by the resulting type."
                        >>
                        >>OK, Thanx. I've read the 1989 edition of the standard 10 or so years
                        >>ago and I had in mind that this would result in implementation-defined
                        >>behavior, but I probably confused that with the signed integer case
                        >>(which also is not implementation-defined but undefined if I read the
                        >>the standard correctly).
                        >
                        It was in C89 but no longer in C99.
                        It's undefined in both C89/C90 and C99.

                        C99 6.5p5:

                        If an _exceptional condition_ occurs during the evaluation of an
                        expression (that is, if the result is not mathematically defined
                        or not in the range of representable values for its type), the
                        behavior is undefined.

                        C90 has the same wording.

                        Perhaps you're thinking of C99's change in the semantics of
                        conversions. In C99, a conversion to a signed type of a value that
                        can't be represented in that type either yields an
                        implementation-defined result or raises an implementation-defined
                        signal (C99 6.3.1.3p3); in C90, the result is implementation-defined
                        (it couldn't raise a signal).

                        (Out-of-range conversions to a floating-point type invoke undefined
                        behavior in both C90 and C99.)

                        --
                        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                        Nokia
                        "We must do something. This is something. Therefore, we must do this."
                        -- Antony Jay and Jonathan Lynn, "Yes Minister"

                        Comment

                        • Barry Schwarz

                          #13
                          Re: Negative values in unsigned int

                          On Wed, 17 Sep 2008 21:30:22 -0700, Keith Thompson <kst-u@mib.org>
                          wrote:
                          >Barry Schwarz <schwarzb@dqel. comwrites:
                          >On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <urs@isnogud.es cape.de>
                          >wrote:
                          >>>jameskuyper@ verizon.net writes:
                          >>>
                          >>>No. It is standard-defined behavior. Section 6.2.5p9 says:
                          >>>>
                          >>>"A computation involving unsigned operands can never overflow, because
                          >>>a result that cannot be represented by the resulting unsigned integer
                          >>>type is reduced modulo the number that is one greater than the largest
                          >>>value that can be represented by the resulting type."
                          >>>
                          >>>OK, Thanx. I've read the 1989 edition of the standard 10 or so years
                          >>>ago and I had in mind that this would result in implementation-defined
                          >>>behavior, but I probably confused that with the signed integer case
                          >>>(which also is not implementation-defined but undefined if I read the
                          >>>the standard correctly).
                          >>
                          >It was in C89 but no longer in C99.
                          >
                          >It's undefined in both C89/C90 and C99.
                          >
                          >C99 6.5p5:
                          >
                          If an _exceptional condition_ occurs during the evaluation of an
                          expression (that is, if the result is not mathematically defined
                          or not in the range of representable values for its type), the
                          behavior is undefined.
                          >
                          >C90 has the same wording.
                          >
                          >Perhaps you're thinking of C99's change in the semantics of
                          >conversions. In C99, a conversion to a signed type of a value that
                          >can't be represented in that type either yields an
                          >implementati on-defined result or raises an implementation-defined
                          >signal (C99 6.3.1.3p3); in C90, the result is implementation-defined
                          >(it couldn't raise a signal).
                          >
                          >(Out-of-range conversions to a floating-point type invoke undefined
                          >behavior in both C90 and C99.)
                          But the thread (or at least what I could see of it) appeared to be
                          talking about converting an unsigned value to a signed integer and for
                          C99 the relevant paragraph seems to be 6.3.1.3-3 which says
                          "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."

                          --
                          Remove del for email

                          Comment

                          • Keith Thompson

                            #14
                            Re: Negative values in unsigned int

                            Barry Schwarz <schwarzb@dqel. comwrites:
                            On Wed, 17 Sep 2008 21:30:22 -0700, Keith Thompson <kst-u@mib.org>
                            wrote:
                            >
                            >>Barry Schwarz <schwarzb@dqel. comwrites:
                            >>On 17 Sep 2008 09:58:28 +0200, Urs Thuermann <urs@isnogud.es cape.de>
                            >>wrote:
                            [...]
                            >>>>OK, Thanx. I've read the 1989 edition of the standard 10 or so years
                            >>>>ago and I had in mind that this would result in implementation-defined
                            >>>>behavior, but I probably confused that with the signed integer case
                            >>>>(which also is not implementation-defined but undefined if I read the
                            >>>>the standard correctly).
                            >>>
                            >>It was in C89 but no longer in C99.
                            >>
                            >>It's undefined in both C89/C90 and C99.
                            >>
                            >>C99 6.5p5:
                            >>
                            > If an _exceptional condition_ occurs during the evaluation of an
                            > expression (that is, if the result is not mathematically defined
                            > or not in the range of representable values for its type), the
                            > behavior is undefined.
                            >>
                            >>C90 has the same wording.
                            >>
                            >>Perhaps you're thinking of C99's change in the semantics of
                            >>conversions . In C99, a conversion to a signed type of a value that
                            >>can't be represented in that type either yields an
                            >>implementatio n-defined result or raises an implementation-defined
                            >>signal (C99 6.3.1.3p3); in C90, the result is implementation-defined
                            >>(it couldn't raise a signal).
                            >>
                            >>(Out-of-range conversions to a floating-point type invoke undefined
                            >>behavior in both C90 and C99.)
                            >
                            But the thread (or at least what I could see of it) appeared to be
                            talking about converting an unsigned value to a signed integer and for
                            C99 the relevant paragraph seems to be 6.3.1.3-3 which says
                            "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."
                            Then I'm unclear on what you meant by "It was in C89 but no longer in
                            C99." I thought you meant that something (out-of-range conversion to
                            a signed type, probably) was undefined in C89, but is no longer
                            undefined in C99, which is not the case.

                            --
                            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                            Nokia
                            "We must do something. This is something. Therefore, we must do this."
                            -- Antony Jay and Jonathan Lynn, "Yes Minister"

                            Comment

                            Working...