Re: Wrong

Discussion in 'C++' started by Joshua Maurice, Apr 17, 2010.

  1. On Apr 17, 12:49 pm, "Leigh Johnston" <> wrote:
    > A certain regular of this newsgroup thinks the following code is not wrong,
    > discuss.
    >
    > void foo()
    > {
    >     std::vector<int> v;
    >     v.reserve(2);
    >     v.push_back(41);
    >     *(&v[0]+1) = 42;
    >
    > }
    >
    > The actual definition of "wrong" may vary from individual to individual as
    > does common sense so it seems.
    >
    > This may help:


    If by wrong, you mean undefined behavior, then yes. The push_back is
    fine, but the next line writes to an area which has been reserved but
    not in the size. I know of several debug implementations of the
    standard library which will crash horribly and report the error of the
    code.
     
    Joshua Maurice, Apr 17, 2010
    #1
    1. Advertising

  2. Joshua Maurice

    Kai-Uwe Bux Guest

    Joshua Maurice wrote:

    > On Apr 17, 12:49 pm, "Leigh Johnston" <> wrote:
    >> A certain regular of this newsgroup thinks the following code is not
    >> wrong, discuss.
    >>
    >> void foo()
    >> {
    >> std::vector<int> v;
    >> v.reserve(2);
    >> v.push_back(41);
    >> *(&v[0]+1) = 42;
    >>
    >> }
    >>
    >> The actual definition of "wrong" may vary from individual to individual
    >> as does common sense so it seems.
    >>
    >> This may help:

    >
    > If by wrong, you mean undefined behavior, then yes. The push_back is
    > fine, but the next line writes to an area which has been reserved but
    > not in the size.


    a) Huh? At

    *(&v[0]+1) = 42

    the size is already 1, because of the previous push_back. So, I don't see a
    write to something not in the size.

    > I know of several debug implementations of the
    > standard library which will crash horribly and report the error of the
    > code.


    That would be interesting. Even replacing 1 by 2:

    *( &v[0] + 2 ) = 42

    I am aware only of implementations that would catch v[2] = 42. The &v[0]+2
    is effectively bypassing the library implementation since &v[0] returns a
    plain pointer, which then is subject to ordinary pointer arithmetic. If an
    implementation catches an out-of-bounds error here, it would not be because
    of the way the _library_ is implemented.


    Also: the pointer arithmetic is actually not out of bounds.


    Upshot: I don't see undefined behavior in the code.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Apr 17, 2010
    #2
    1. Advertising

  3. Joshua Maurice

    Kai-Uwe Bux Guest

    Kai-Uwe Bux wrote:

    > Joshua Maurice wrote:
    >
    >> On Apr 17, 12:49 pm, "Leigh Johnston" <> wrote:
    >>> A certain regular of this newsgroup thinks the following code is not
    >>> wrong, discuss.
    >>>
    >>> void foo()
    >>> {
    >>> std::vector<int> v;
    >>> v.reserve(2);
    >>> v.push_back(41);
    >>> *(&v[0]+1) = 42;
    >>>
    >>> }
    >>>
    >>> The actual definition of "wrong" may vary from individual to individual
    >>> as does common sense so it seems.
    >>>
    >>> This may help:

    >>
    >> If by wrong, you mean undefined behavior, then yes. The push_back is
    >> fine, but the next line writes to an area which has been reserved but
    >> not in the size.

    >
    > a) Huh? At
    >
    > *(&v[0]+1) = 42
    >
    > the size is already 1, because of the previous push_back. So, I don't see
    > a write to something not in the size.


    Oops, my fault: I cannot count :)


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Apr 17, 2010
    #3
  4. * Joshua Maurice:
    > On Apr 17, 12:49 pm, "Leigh Johnston" <> wrote:
    >> A certain regular of this newsgroup thinks the following code is not wrong,
    >> discuss.
    >>
    >> void foo()
    >> {
    >> std::vector<int> v;
    >> v.reserve(2);
    >> v.push_back(41);
    >> *(&v[0]+1) = 42;
    >>
    >> }
    >>
    >> The actual definition of "wrong" may vary from individual to individual as
    >> does common sense so it seems.
    >>
    >> This may help:

    >
    > If by wrong, you mean undefined behavior, then yes. The push_back is
    > fine, but the next line writes to an area which has been reserved but
    > not in the size. I know of several debug implementations of the
    > standard library which will crash horribly and report the error of the
    > code.


    Example?


    Cheers,

    - Alf
     
    Alf P. Steinbach, Apr 18, 2010
    #4
  5. On Apr 17, 8:36 pm, "Alf P. Steinbach" <> wrote:
    > * Joshua Maurice:
    >
    >
    >
    > > On Apr 17, 12:49 pm, "Leigh Johnston" <> wrote:
    > >> A certain regular of this newsgroup thinks the following code is not wrong,
    > >> discuss.

    >
    > >> void foo()
    > >> {
    > >>     std::vector<int> v;
    > >>     v.reserve(2);
    > >>     v.push_back(41);
    > >>     *(&v[0]+1) = 42;

    >
    > >> }

    >
    > >> The actual definition of "wrong" may vary from individual to individual as
    > >> does common sense so it seems.

    >
    > >> This may help:

    >
    > > If by wrong, you mean undefined behavior, then yes. The push_back is
    > > fine, but the next line writes to an area which has been reserved but
    > > not in the size. I know of several debug implementations of the
    > > standard library which will crash horribly and report the error of the
    > > code.

    >
    > Example?


    My mistake. I am incorrect. I thought visual studios debug iterators
    would catch it. However, the undefined behavior line in question was
    not using iterators but raw pointers. I was thinking of the following
    example, which visual studios debug iterators do catch.

    #include <vector>
    using namespace std;
    int main()
    {
    std::vector<int> v;
    v.reserve(2);
    v.push_back(41);
    *(v.begin()+1) = 42;
    }
     
    Joshua Maurice, Apr 18, 2010
    #5
  6. Alf P. Steinbach <> wrote:
    >> If by wrong, you mean undefined behavior, then yes. The push_back is
    >> fine, but the next line writes to an area which has been reserved but
    >> not in the size. I know of several debug implementations of the
    >> standard library which will crash horribly and report the error of the
    >> code.

    >
    > Example?


    MS Visual C++, when compiling in debug mode.

    gcc when using the _GLIBCXX_DEBUG preprocessor macro.
     
    Juha Nieminen, Apr 18, 2010
    #6
  7. * Joshua Maurice:
    > On Apr 17, 8:36 pm, "Alf P. Steinbach" <> wrote:
    >> * Joshua Maurice:
    >>
    >>
    >>
    >>> On Apr 17, 12:49 pm, "Leigh Johnston" <> wrote:
    >>>> A certain regular of this newsgroup thinks the following code is not wrong,
    >>>> discuss.
    >>>> void foo()
    >>>> {
    >>>> std::vector<int> v;
    >>>> v.reserve(2);
    >>>> v.push_back(41);
    >>>> *(&v[0]+1) = 42;
    >>>> }
    >>>> The actual definition of "wrong" may vary from individual to individual as
    >>>> does common sense so it seems.
    >>>> This may help:
    >>> If by wrong, you mean undefined behavior, then yes. The push_back is
    >>> fine, but the next line writes to an area which has been reserved but
    >>> not in the size. I know of several debug implementations of the
    >>> standard library which will crash horribly and report the error of the
    >>> code.

    >> Example?

    >
    > My mistake. I am incorrect. I thought visual studios debug iterators
    > would catch it. However, the undefined behavior line in question was
    > not using iterators but raw pointers.


    Yes. I don't think it's undefined behavior (as I see it it's guaranteed and
    well-defined, because the standard guarantees that there is a raw array of size
    2 or larger, and, since it can't be put in place after the reserve call, that
    that array is the buffer accessible via &v[0], and the standard also guarantees
    pointer access of raw arrays). I think it's just bad practice, although like
    "goto" there may be circumstances where it's The Lesser Evil(TM).


    > I was thinking of the following
    > example, which visual studios debug iterators do catch.
    >
    > #include <vector>
    > using namespace std;
    > int main()
    > {
    > std::vector<int> v;
    > v.reserve(2);
    > v.push_back(41);
    > *(v.begin()+1) = 42;
    > }


    Yes. :)

    For other readers: here the +1 advances the iterator to end(), instead of being
    raw pointer arithmetic advancing a raw pointer.


    Cheers,

    - Alf
     
    Alf P. Steinbach, Apr 18, 2010
    #7
  8. * Juha Nieminen:
    > Alf P. Steinbach <> wrote:
    >>> If by wrong, you mean undefined behavior, then yes. The push_back is
    >>> fine, but the next line writes to an area which has been reserved but
    >>> not in the size. I know of several debug implementations of the
    >>> standard library which will crash horribly and report the error of the
    >>> code.

    >> Example?

    >
    > MS Visual C++, when compiling in debug mode.
    >
    > gcc when using the _GLIBCXX_DEBUG preprocessor macro.


    Would you care to present a complete little example, with actual result?


    Cheers,

    - Alf
     
    Alf P. Steinbach, Apr 18, 2010
    #8
  9. Alf P. Steinbach <> wrote:
    > * Juha Nieminen:
    >> Alf P. Steinbach <> wrote:
    >>>> If by wrong, you mean undefined behavior, then yes. The push_back is
    >>>> fine, but the next line writes to an area which has been reserved but
    >>>> not in the size. I know of several debug implementations of the
    >>>> standard library which will crash horribly and report the error of the
    >>>> code.
    >>> Example?

    >>
    >> MS Visual C++, when compiling in debug mode.
    >>
    >> gcc when using the _GLIBCXX_DEBUG preprocessor macro.

    >
    > Would you care to present a complete little example, with actual result?


    Ok, you got me. I was thinking about actually indexing the vector past
    its size, but the original code actually takes a raw pointer to the first
    element and then uses pointer arithmetic to get past the size. Those
    compilers I mentioned won't catch that as any kind of error, even in debug
    mode.

    Ok, I can't see why the given example code would misbehave (when using
    basic types) in any system with any compiler with any compiler settings.
     
    Juha Nieminen, Apr 18, 2010
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Salisha Khan
    Replies:
    1
    Views:
    11,706
    JohnFol
    Aug 1, 2003
  2. Replies:
    2
    Views:
    404
  3. Pial
    Replies:
    4
    Views:
    57,075
    Phatman
    Aug 27, 2010
  4. Paul Leventis

    Re: Quartus bug or wrong VHDL?

    Paul Leventis, Jun 24, 2003, in forum: VHDL
    Replies:
    0
    Views:
    2,517
    Paul Leventis
    Jun 24, 2003
  5. Matthew
    Replies:
    7
    Views:
    878
    Priscilla Walmsley
    Jan 7, 2005
Loading...

Share This Page