Dereference an array pointer... UB?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?=

    Dereference an array pointer... UB?


    Do you think we can reach any kind of consensus on whether the
    following code's behaviour is undefined by the Standard?

    int my_array[5];

    int const *const pend = *(&my_array + 1);

    Considering the syntax of the language, then we definitely do
    dereference an invalid pointer... but if we consider the mechanics of the
    language, then we know that nothing "happens" when we dereference a pointer
    to an array, because arrays are dealt with in terms of pointers.

    --
    Tomás Ó hÉilidhe
  • Malcolm McLean

    #2
    Re: Dereference an array pointer... UB?


    "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
    >
    Do you think we can reach any kind of consensus on whether the
    following code's behaviour is undefined by the Standard?
    >
    int my_array[5];
    >
    int const *const pend = *(&my_array + 1);
    >
    Considering the syntax of the language, then we definitely do
    dereference an invalid pointer... but if we consider the mechanics of the
    language, then we know that nothing "happens" when we dereference a
    pointer to an array, because arrays are dealt with in terms of pointers.
    >
    my_array and &my_array resolve to the same thing. It's a quirk of the
    language.

    --
    Free games and programming goodies.


    Comment

    • Ben Bacarisse

      #3
      Re: Dereference an array pointer... UB?

      "Malcolm McLean" <regniztar@btin ternet.comwrite s:
      "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
      >>
      > Do you think we can reach any kind of consensus on whether the
      >following code's behaviour is undefined by the Standard?
      >>
      > int my_array[5];
      >>
      > int const *const pend = *(&my_array + 1);
      >>
      > Considering the syntax of the language, then we definitely do
      >dereference an invalid pointer... but if we consider the mechanics of the
      >language, then we know that nothing "happens" when we dereference a
      >pointer to an array, because arrays are dealt with in terms of pointers.
      >>
      my_array and &my_array resolve to the same thing. It's a quirk of the
      language.
      But my_array + 1 and &my_array + 1 don't. The word "resolve" allows you
      to be right (since you can mean what you like by it) but it hides the
      important difference between the two expressions -- their type.

      --
      Ben.

      Comment

      • vippstar@gmail.com

        #4
        Re: Dereference an array pointer... UB?

        On Feb 11, 8:36 pm, "Malcolm McLean" <regniz...@btin ternet.comwrote :
        "Tomás Ó hÉilidhe" <t...@lavabit.c omwrote in message
        >
        Do you think we can reach any kind of consensus on whether the
        following code's behaviour is undefined by the Standard?
        >
        int my_array[5];
        >
        int const *const pend = *(&my_array + 1);
        >
        Considering the syntax of the language, then we definitely do
        dereference an invalid pointer... but if we consider the mechanics of the
        language, then we know that nothing "happens" when we dereference a
        pointer to an array, because arrays are dealt with in terms of pointers.
        >
        my_array and &my_array resolve to the same thing. It's a quirk of the
        language.
        Only in value context.
        I believe it's undefined behavior.
        You dereference a pointer past the end of an object.
        It is essentially the same with
        --
        int *foo;
        int *bar = *(&foo+1);
        --
        Which is invalid.
        &foo is an object, which can be treated as an array with 1 element.
        Therefore, &foo+1 is a valid pointer, which cannot be dereferenced,
        however you do dereference it.

        It is invalid.

        I am, however, not 100% sure about this, but it appears to be logical
        and correct.

        Comment

        • =?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?=

          #5
          Re: Dereference an array pointer... UB?

          Malcolm McLean:
          my_array and &my_array resolve to the same thing. It's a quirk of the
          language.

          I'm not sure what you mean by that.

          my_array is a int[X] (and it decays to an int*)

          &my_array is a int(*)[X] (and it DOESN'T decay to an int*)

          --
          Tomás Ó hÉilidhe

          Comment

          • Malcolm McLean

            #6
            Re: Dereference an array pointer... UB?

            "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
            Malcolm McLean:
            >
            >my_array and &my_array resolve to the same thing. It's a quirk of the
            >language.
            >
            >
            I'm not sure what you mean by that.
            >
            my_array is a int[X] (and it decays to an int*)
            >
            &my_array is a int(*)[X] (and it DOESN'T decay to an int*)
            >
            That was an error on my part.

            --
            Free games and programming goodies.


            Comment

            • =?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?=

              #7
              Re: Dereference an array pointer... UB?

              vippstar:

              It is essentially the same with
              --
              int *foo;
              int *bar = *(&foo+1);
              --
              Which is invalid.

              No no no, they're not the same. Syntactically, yes they're the same,
              but mechanically, they're not. The difference is that *(&foo+1) is an
              actual value, it results in a value being read from memory.
              &foo is an object, which can be treated as an array with 1 element.
              Therefore, &foo+1 is a valid pointer, which cannot be dereferenced,
              however you do dereference it.

              You're correct.

              It is invalid.

              I'm not sure I agrees, because an array doesn't have a value. Its elements
              do, but not the array itself.

              --
              Tomás Ó hÉilidhe

              Comment

              • vippstar@gmail.com

                #8
                Re: Dereference an array pointer... UB?

                On Feb 11, 9:52 pm, "Tomás Ó hÉilidhe" <t...@lavabit.c omwrote:
                vippstar:
                >
                It is essentially the same with
                --
                int *foo;
                int *bar = *(&foo+1);
                --
                Which is invalid.
                >
                No no no, they're not the same. Syntactically, yes they're the same,
                but mechanically, they're not. The difference is that *(&foo+1) is an
                actual value, it results in a value being read from memory.
                I am not sure what you are talking about, however, both &foo and
                &your_array are pointers.
                int * and int (*)[X} respectively.
                You point one past the end of what.. they point to, which is valid but
                cannot dereferenced.
                *(&foo+1) is not valid.
                &foo is an object, which can be treated as an array with 1 element.
                Therefore, &foo+1 is a valid pointer, which cannot be dereferenced,
                however you do dereference it.
                >
                You're correct.
                And the same applies for &your_array. They are both pointers that
                point to 1 valid thing. (foo and your_array respectively)
                It is invalid.
                >
                I'm not sure I agrees, because an array doesn't have a value. Its elements
                do, but not the array itself.
                We are, however not talking about arrays, but pointers.
                I insist that my example is the same with what you are trying to do,
                and they are both invalid.
                I suggest to think of another solution for your problem, and if that
                is not possible, consider if that is the _only_ way.

                Comment

                • =?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?=

                  #9
                  Re: Dereference an array pointer... UB?

                  vippstar:

                  int * and int (*)[X] respectively.
                  You point one past the end of what.. they point to, which is valid but
                  cannot dereferenced.

                  Dereference an int(*)[X] and you get an int[X], which doesn't have a
                  value, and so it couldn't result in an out-of-bounds memory access because
                  there shouldn't be any memory access at all if arrays don't have values.

                  --
                  Tomás Ó hÉilidhe

                  Comment

                  • Marc Boyer

                    #10
                    Re: Dereference an array pointer... UB?

                    On 2008-02-11, Malcolm McLean <regniztar@btin ternet.comwrote :
                    >
                    "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
                    >>
                    > Do you think we can reach any kind of consensus on whether the
                    >following code's behaviour is undefined by the Standard?
                    >>
                    > int my_array[5];
                    >>
                    > int const *const pend = *(&my_array + 1);
                    >>
                    > Considering the syntax of the language, then we definitely do
                    >dereference an invalid pointer... but if we consider the mechanics of the
                    >language, then we know that nothing "happens" when we dereference a
                    >pointer to an array, because arrays are dealt with in terms of pointers.
                    >>
                    my_array and &my_array resolve to the same thing. It's a quirk of the
                    language.
                    No.
                    6.3.2.1/3
                    "Except when it is the operand of the sizeof operator /or the
                    unary & operator/ [...] an expression that has type "array of type"
                    is converted to an expression with type "pointer to type" that
                    points to the initial element of the array object".

                    Marc Boyer

                    Comment

                    • Old Wolf

                      #11
                      Re: Dereference an array pointer... UB?

                      On Feb 12, 7:21 am, "Tomás Ó hÉilidhe" <t...@lavabit.c omwrote:
                      Do you think we can reach any kind of consensus on whether the
                      following code's behaviour is undefined by the Standard?
                      >
                      int my_array[5];
                      >
                      int const *const pend = *(&my_array + 1);
                      &X + 1 is a pointer to one-past-the-end.
                      Dereferencing such a pointer this causes UB.
                      Doesn't matter what data type the pointer is.

                      Comment

                      • =?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?=

                        #12
                        Re: Dereference an array pointer... UB?

                        Old Wolf:
                        &X + 1 is a pointer to one-past-the-end.
                        Dereferencing such a pointer this causes UB.
                        Doesn't matter what data type the pointer is.

                        That's a very superficial way of looking at it.

                        The REASON why it's UB to dereference a pointer to one-past-the-last is
                        because it could result in an out-of-bounds memory access.

                        With a pointer to an array, nothing happens when you dereference it -- all
                        that happens is that you've got an expression of int[X] rather than int(*)
                        [X].

                        --
                        Tomás Ó hÉilidhe

                        Comment

                        • =?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?=

                          #13
                          Re: Dereference an array pointer... UB?

                          Tomás Ó hÉilidhe:
                          With a pointer to an array, nothing happens when you dereference it --
                          all that happens is that you've got an expression of int[X] rather
                          than int(*) [X].

                          In fact, I'd go one step further to say that the following should be legal:


                          int (*parr)[X] = (int(*)[X])798797; /* Some random address (but which
                          doesn't cause a trap)

                          *parr;


                          --
                          Tomás Ó hÉilidhe

                          Comment

                          • Thad Smith

                            #14
                            Re: Dereference an array pointer... UB?

                            Tomás Ó hÉilidhe wrote:
                            Old Wolf:
                            >
                            >&X + 1 is a pointer to one-past-the-end.
                            >Dereferencin g such a pointer this causes UB.
                            >Doesn't matter what data type the pointer is.
                            >
                            That's a very superficial way of looking at it.
                            >
                            The REASON why it's UB to dereference a pointer to one-past-the-last is
                            because it could result in an out-of-bounds memory access.
                            Perhaps your point is that the Standard /should/ have defined a behavior,
                            but didn't. I agree with that.

                            My reading is that a unary * applied to a function pointer is defined. A
                            unary * applied to a pointer to an object is defined. There are no other
                            cases defined for the unary * operator. Since &X+1 technically isn't a
                            pointer to an object, *(&X+1) is undefined by omission.

                            --
                            Thad

                            Comment

                            • Keith Thompson

                              #15
                              Re: Dereference an array pointer... UB?

                              "Tomás Ó hÉilidhe" <toe@lavabit.co mwrites:
                              Old Wolf:
                              >&X + 1 is a pointer to one-past-the-end.
                              >Dereferencin g such a pointer this causes UB.
                              >Doesn't matter what data type the pointer is.
                              >
                              That's a very superficial way of looking at it.
                              >
                              The REASON why it's UB to dereference a pointer to one-past-the-last is
                              because it could result in an out-of-bounds memory access.
                              The reason why it's UB is that the standard doesn't define the
                              behavior. (Though you've correctly described the rationale for what
                              the standard says.)
                              With a pointer to an array, nothing happens when you dereference it -- all
                              that happens is that you've got an expression of int[X] rather than int(*)
                              [X].
                              An expression of array type is converted to a pointer. There has to
                              be something to convert in the first place.

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

                              Comment

                              Working...