is &(vector[0]) always valid?

Discussion in 'C++' started by John Salmon, Jan 20, 2007.

  1. John Salmon

    John Salmon Guest

    I was under the impression that the following was always valid:

    std::vector<T> v;
    ..
    T *p = &(v[0]);

    But I was recently told that care was needed in case the vector was
    empty, i.e., when v.size() == 0.

    I'm hoping that the above expression is fine, even if v is empty, but
    that if you try to dereference p, you're in trouble.

    If the above isn't ok, I'd have to write:

    T *p = (v.size()!=0)? &(v[0]) : 0;

    I took a look in the C++98 standard, and couldn't find anything to
    confirm my hope. I see from Table 68 that the expression has the
    "operational sematics" of

    &(*(v.begin() + 0))

    which sure *seems* like it might in turn be "operationally equivalent"
    to v.begin(), which sure seems safe, even for an empty vector. But I
    now feel myself to be on very thin ice.

    So, can I write:

    T *p = &(v[0]);

    or do I have to write:

    T *p = (v.size()!=0)? &(v[0]) : 0;

    Thanks,
    John Salmon

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    John Salmon, Jan 20, 2007
    #1
    1. Advertising

  2. John Salmon wrote:
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.
    >
    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.


    It may work on your platform, however the C++ standard says it's
    undefined. Hence, it may work for you today but it may also break tomorrow.

    >
    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    Right.
     
    Gianni Mariani, Jan 20, 2007
    #2
    1. Advertising

  3. John Salmon

    Alan Johnson Guest

    John Salmon wrote:
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.
    >
    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.
    >
    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of
    >
    > &(*(v.begin() + 0))
    >
    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.
    >
    > So, can I write:
    >
    > T *p = &(v[0]);
    >
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > Thanks,
    > John Salmon
    >


    v[0] is NOT valid for an empty vector, and therefore &v[0] is not valid
    either. You are right about the operational semantics, but neither is
    that expression valid. If the vector is empty, then begin() == end(),
    and you are therefore "dereferencing" the end() iterator.

    As for the alternate expression you propose, using empty() rather than
    size() would be more idiomatic, and might be more efficient, depending
    on the implementation:

    T *p = v.empty() ? 0 : &(v[0]) ;

    --
    Alan Johnson

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Alan Johnson, Jan 20, 2007
    #3
  4. John Salmon

    Carl Barron Guest

    In article <>, John Salmon
    <> wrote:

    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.

    its not valid if v.size()==0.
    template <class T,class A>
    inline T *data(std::vector<T,A> &v)
    {
    return v.empty() ? 0: &v[0];
    }
    is an easy work around. Recent drafts of the standard provide
    vector with a data() member function which does this, but your
    implementation probably does not.

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Carl Barron, Jan 20, 2007
    #4
  5. John Salmon

    Kai-Uwe Bux Guest

    John Salmon wrote:

    >
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.
    >
    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.


    If v is empty, once you evaluate v[0] you have undefined behavior. More
    importantly, an implementation of std::vector<> is perfectly free and maybe
    even well-advised to do something like:

    T& operator[] ( size_type i ) {
    assert( i < this->size() );
    return( this->data );
    }

    Because of the assert(), your program could crash depending on compilation
    options.

    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of
    >
    > &(*(v.begin() + 0))
    >
    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.
    >
    > So, can I write:
    >
    > T *p = &(v[0]);
    >
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    Why do you insist on using T* anyway? What is the reason not to use
    std::vector<T>::iterator?


    Best

    Kai-Uwe Bux

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Kai-Uwe Bux, Jan 20, 2007
    #5
  6. On Sat, 20 Jan 2007 07:21:08 GMT, John Salmon wrote:
    >So, can I write:
    >
    >T *p = &(v[0]);
    >
    > or do I have to write:
    >
    >T *p = (v.size()!=0)? &(v[0]) : 0;


    What would be the address of the first element of an empty vector?

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Roland Pibinger, Jan 20, 2007
    #6
  7. "John Salmon" <> wrote in message
    news:...

    > I was under the impression that the following was always valid:


    > std::vector<T> v;


    > T *p = &(v[0]);


    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.


    Whoever told you that is correct.

    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.


    Sorry to dash your hopes, but...

    > If the above isn't ok, I'd have to write:


    > T *p = (v.size()!=0)? &(v[0]) : 0;


    Right.

    >
    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of
    >
    > &(*(v.begin() + 0))
    >
    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.


    You are. v.begin() + 0 is always equivalent to v.begin(), but &(*v.begin())
    is undefined if v is empty.

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Andrew Koenig, Jan 20, 2007
    #7
  8. In article <>, John Salmon
    <> writes
    >I was under the impression that the following was always valid:
    >
    >std::vector<T> v;
    >.
    >T *p = &(v[0]);
    >
    >But I was recently told that care was needed in case the vector was
    >empty, i.e., when v.size() == 0.


    You were correctly informed. The problem is that v[0] has undefined
    behaviour if there are no elements. That means that &(v[0]) has
    undefined behaviour. This is not that unreasonable because an empty
    vector does not have a location for any element so there will be no
    address.

    Changing this would have required a special rule for &(v[0]). Instead
    you must write something like:

    T *p = v.size() ? &(v[0]) : 0;

    If there is any possibility that v is an empty vector. (There are
    several variations on the above definition but I tend to use a limited
    subset of the member functions of vector rather than remember the exact
    spelling of all of them.)


    --
    Francis Glassborow ACCU
    Author of 'You Can Do It!' and "You Can Program in C++"
    see http://www.spellen.org/youcandoit
    For project ideas and contributions: http://www.spellen.org/youcandoit/projects

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Francis Glassborow, Jan 20, 2007
    #8
  9. John Salmon

    James Kanze Guest

    John Salmon wrote:
    > I was under the impression that the following was always valid:


    > std::vector<T> v;
    > .
    > T *p = &(v[0]);


    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.


    > I'm hoping that the above expression is fine, even if v is empty,


    It's not. It's undefined behavior, and will core dump on some
    implementations. (It core dumps with g++ 4.0.1, for example, or
    with VC++ 8.)

    > but that if you try to dereference p, you're in trouble.


    > If the above isn't ok, I'd have to write:


    > T *p = (v.size()!=0)? &(v[0]) : 0;


    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of


    > &(*(v.begin() + 0))


    No. The expression a[n] is the equivalent of *(v.begin() + 0)
    (which is presumably the equivalent of *v.begin()). If
    v.begin() == v.end(), however, *v.begin() is undefined behavior.

    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.


    I'd say that the ice has already broken. Your code causes a
    run-time error (core dump, or its moral equivalent under
    Windows) with two of the three compilers I regularly use.

    > So, can I write:


    > T *p = &(v[0]);


    > or do I have to write:


    > T *p = (v.size()!=0)? &(v[0]) : 0;


    The latter.

    Given the particular guarantee for std::vector, I wonder if an
    additional member function, data() might not be in order. A
    function which could be required to return a null pointer if the
    vector is empty.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    James Kanze, Jan 20, 2007
    #9
  10. In article <>,
    (John Salmon) wrote:

    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.
    >
    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.
    >
    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of
    >
    > &(*(v.begin() + 0))
    >
    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.
    >
    > So, can I write:
    >
    > T *p = &(v[0]);
    >
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    You have to write the latter (unfortunately). It is the dereference
    caused by v[0] which is the trouble maker.

    Fwiw the working draft for C++0X has added a new member function to
    vector so that you no longer have to do this:

    T *p = v.data();

    Reference LWG 464:
    http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#464

    Your vendor may or may not yet support this new member as C++0X isn't
    official yet.

    -Howard

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Howard Hinnant, Jan 20, 2007
    #10
  11. John Salmon

    Jorgen Grahn Guest

    ["Followup-To:" header set to comp.lang.c++.]

    On Sat, 20 Jan 2007 07:21:08 GMT, John Salmon <> wrote:
    >
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.


    Or when v.empty().

    ..
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    That, or:

    T *p = v.empty()? 0: &(v[0]);

    std::vector<T>::size() is constant time, I think, but that's not the case
    for other containers. So when you really want to test for (non-)emptiness,
    it's good to make a habit of using empty().

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
    \X/ snipabacken.dyndns.org> R'lyeh wgah'nagl fhtagn!

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Jorgen Grahn, Jan 20, 2007
    #11
  12. John Salmon

    whyglinux Guest

    John Salmon wrote:
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.
    >
    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.
    >
    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of
    >
    > &(*(v.begin() + 0))
    >
    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.
    >
    > So, can I write:
    >
    > T *p = &(v[0]);
    >
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > Thanks,
    > John Salmon
    >
    > ---
    > [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    > [ your news-reader. If that fails, use mailto: ]
    > [ --- Please see the FAQ before posting. --- ]
    > [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]


    Yes, it's undefined.

    v[0] is equivalent to *v.begin(). Whether v is an empty vector or not,
    v.begin() returns a valid iterator. But if v is empty, v.begin(), like
    v.end(), is not a valid dereferenceable iterator, so *v.begin() is
    undefined.

    Note though, &(*(v.begin() + 0)) is not, as you said, "operationally
    equivalent" to v.begin() because v.begin() returns an object of the
    vector<T>'s iterator type while &(*(v.begin() + 0)) should return a
    type of pointer to T (since operator * is overloaded here), and the
    iterator type needs not to be the same as a pointer to T.

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    whyglinux, Jan 20, 2007
    #12
  13. John Salmon

    Lynn Guest

    > std::vector<T> v;
    > .
    > T *p = &(v[0]);


    This works in Visual C++ 2003. It crashes when the size is
    zero in Visual C++ 2005. I fixing this all over our code right
    now.

    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.


    Yes, true.

    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    Yes, this should work OK.

    Lynn


    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Lynn, Jan 20, 2007
    #13
  14. John Salmon

    Guest

    John Salmon wrote:
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > .
    > T *p = &(v[0]);
    >



    I've often had this question myself. Even if this worked, isn't it
    _very_ dangerous? Consider the following:

    std::vector<T> v(1);

    T dummy;

    v.push_back(dummy);

    T * p = &(v[0]);


    v.push_back(dummy);

    v.push_back(dummy);

    // does p still point to anything valid at this point? Since the
    push_back operations, perhaps
    // internally the vector resized itself. I wouldn't expect that the
    vector object keep the same internal
    // memory.

    T first_element = p[0]; //is p still valid?

    // Thoughts?

    Dave

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    , Jan 22, 2007
    #14
  15. wrote:
    > John Salmon wrote:
    >> I was under the impression that the following was always valid:
    >>
    >> std::vector<T> v;
    >> .
    >> T *p = &(v[0]);
    >>

    >
    >
    > I've often had this question myself. Even if this worked, isn't it
    > _very_ dangerous? Consider the following:
    >
    > std::vector<T> v(1);
    >
    > T dummy;
    >
    > v.push_back(dummy);
    >
    > T * p = &(v[0]);
    >
    >
    > v.push_back(dummy);
    >
    > v.push_back(dummy);
    >
    > // does p still point to anything valid at this point? Since the
    > push_back operations, perhaps
    > // internally the vector resized itself. I wouldn't expect that the
    > vector object keep the same internal
    > // memory.
    >
    > T first_element = p[0]; //is p still valid?
    >
    > // Thoughts?


    This is spelled out quite clearly; after a push_back that
    can cause a vector to grow beyond its capacity, iterators
    and pointers to its old elements are invalidated. In your
    example, p is invalidated by the first call to v.push_back
    after p was initialized.

    It's dangerous is people don't know the rules on when
    iterators and pointers are invalidated, but those rules
    are vital to safe use of containers in any case.

    Further discussion on this line is probably best removed
    from comp.std.c++; followups set.

    -- James

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    James Dennett, Jan 22, 2007
    #15
  16. * John Salmon:
    >
    > So, can I write:
    >
    > T *p = &(v[0]);
    >
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    The latter.

    §23.1/7 "If the container is empty, then 'begin() == end()'".
    §24.1/5 Explaining that one-past-the-end iterators are past-the-end
    values, then "The library never assumes that past-the-end values are
    dereferencable".

    Hence v[0] by equivalence to &(*(begin()+0)) performs an invalid
    dereferencing when the vector is empty. In more practical terms, the
    vector need not have a buffer if it's empty. But I suspect that with
    most compiler and standard library implementations (all?) you can get
    away with it if the vector's /capacity/ is greater than zero.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?

    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Alf P. Steinbach, Jan 22, 2007
    #16
  17. John Salmon wrote:
    > I was under the impression that the following was always valid:
    >
    > std::vector<T> v;
    > ..
    > T *p = &(v[0]);
    >
    > But I was recently told that care was needed in case the vector was
    > empty, i.e., when v.size() == 0.


    You were told correctly. Calling v[x], where x is >= v.size() is
    undefined behavior; period.

    > I'm hoping that the above expression is fine, even if v is empty, but
    > that if you try to dereference p, you're in trouble.
    >
    > If the above isn't ok, I'd have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;
    >
    > I took a look in the C++98 standard, and couldn't find anything to
    > confirm my hope. I see from Table 68 that the expression has the
    > "operational sematics" of
    >
    > &(*(v.begin() + 0))
    >
    > which sure *seems* like it might in turn be "operationally equivalent"
    > to v.begin(), which sure seems safe, even for an empty vector. But I
    > now feel myself to be on very thin ice.
    >
    > So, can I write:
    >
    > T *p = &(v[0]);
    >
    > or do I have to write:
    >
    > T *p = (v.size()!=0)? &(v[0]) : 0;


    You have to write the later (or some variation thereof).

    --
    Clark S. Cox III


    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Clark S. Cox III, Jan 22, 2007
    #17
  18. John Salmon

    James Kanze Guest

    "Alf P. Steinbach" wrote:
    > * John Salmon:


    > > So, can I write:


    > > T *p = &(v[0]);


    > > or do I have to write:


    > > T *p = (v.size()!=0)? &(v[0]) : 0;


    > The latter.


    > §23.1/7 "If the container is empty, then 'begin() == end()'".
    > §24.1/5 Explaining that one-past-the-end iterators are past-the-end
    > values, then "The library never assumes that past-the-end values are
    > dereferencable".


    > Hence v[0] by equivalence to &(*(begin()+0)) performs an invalid
    > dereferencing when the vector is empty. In more practical terms, the
    > vector need not have a buffer if it's empty. But I suspect that with
    > most compiler and standard library implementations (all?) you can get
    > away with it if the vector's /capacity/ is greater than zero.


    Changing the capacity doesn't make it work with g++ nor with
    VC++. There are thus at least two major implementations (the
    two most widely used?) where it actually does fail at runtime.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    James Kanze, Jan 22, 2007
    #18
  19. John Salmon

    peter koch Guest

    James Kanze wrote:
    > "Alf P. Steinbach" wrote:
    > > * John Salmon:

    >
    > > > So, can I write:

    >
    > > > T *p = &(v[0]);

    >
    > > > or do I have to write:

    >
    > > > T *p = (v.size()!=0)? &(v[0]) : 0;

    >
    > > The latter.

    >
    > > §23.1/7 "If the container is empty, then 'begin() == end()'".
    > > §24.1/5 Explaining that one-past-the-end iterators are past-the-end
    > > values, then "The library never assumes that past-the-end values are
    > > dereferencable".

    >
    > > Hence v[0] by equivalence to &(*(begin()+0)) performs an invalid
    > > dereferencing when the vector is empty. In more practical terms, the
    > > vector need not have a buffer if it's empty. But I suspect that with
    > > most compiler and standard library implementations (all?) you can get
    > > away with it if the vector's /capacity/ is greater than zero.

    >
    > Changing the capacity doesn't make it work with g++ nor with
    > VC++. There are thus at least two major implementations (the
    > two most widely used?) where it actually does fail at runtime.


    Which is logical. I do not know of a hardware platform where
    &(*begin()) would physically access memory, so I'd expect &(*begin())
    to return a pointer in all cases when the implementation does not
    perform some kind of explicit check. And that check would be related
    to size, not capacity.

    /Peter


    ---
    [ comp.std.c++ is moderated. To submit articles, try just posting with ]
    [ your news-reader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    peter koch, Jan 23, 2007
    #19
    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. Soren Kuula

    Empty documents always DTD-valid?

    Soren Kuula, Sep 20, 2005, in forum: XML
    Replies:
    2
    Views:
    523
    Richard Tobin
    Sep 20, 2005
  2. pmatos
    Replies:
    6
    Views:
    23,823
  3. Replies:
    8
    Views:
    1,930
    Csaba
    Feb 18, 2006
  4. Javier
    Replies:
    2
    Views:
    569
    James Kanze
    Sep 4, 2007
  5. Rushikesh Joshi
    Replies:
    0
    Views:
    366
    Rushikesh Joshi
    Jul 10, 2004
Loading...

Share This Page