Addressing a &vector<>[i] as a C-array & the C++ standard.

N

Numeromancer

From the C++-FAQ Lite:

http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3

----------------------------
34.3] Is the storage for a std::vector<T> guaranteed to be contiguous? Yes.

This means you the following technique is safe:

#include <vector>
#include "Foo.h" /* get class Foo */

// old-style code that wants an array
void f(Foo* array, unsigned numFoos);

void g()
{
std::vector<Foo> v;
...
f(v.empty() ? NULL : &v[0], v.size()); ↠safe
}

The funny expression v.empty() ? NULL : &v[0] simply passes the NULL
pointer if v is empty, otherwise passes a pointer to the first (zeroth)
element of v. If you know a priori that v is not empty, you can change
that to simply &v[0].
----------------------------

I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?

Thanks,

Tim S.
 
G

Gianni Mariani

Numeromancer wrote:
....
I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?

It is somthing ratified as errata I believe. I heard the next standard
will go as far as saying that basic_string is also contiguous.

I have no concrete reference other than postings by others.
 
K

Kai-Uwe Bux

Numeromancer said:
From the C++-FAQ Lite:

http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3

----------------------------
34.3] Is the storage for a std::vector<T> guaranteed to be contiguous?
Yes.

This means you the following technique is safe:

#include <vector>
#include "Foo.h" /* get class Foo */

// old-style code that wants an array
void f(Foo* array, unsigned numFoos);

void g()
{
std::vector<Foo> v;
...
f(v.empty() ? NULL : &v[0], v.size()); ? safe
}

The funny expression v.empty() ? NULL : &v[0] simply passes the NULL
pointer if v is empty, otherwise passes a pointer to the first (zeroth)
element of v. If you know a priori that v is not empty, you can change
that to simply &v[0].
----------------------------

I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?

So, the FAQ got updated? It used to say that this was pending incorporation
into the standard.

Anyway, you have to look in the 2003 edition. There it is clause 23.2.4/1:

[...] The elements of a vector are stored contiguously, meaning that if v
is a vector<T, Allocator> where T is some type other than bool, then it
obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().


If I remember correctly, for the next iteration, it is planned to extend
this guarantee to std::string.


Best

Kai-Uwe Bux
 
A

Alan Woodland

Numeromancer wrote:
....
// old-style code that wants an array
void f(Foo* array, unsigned numFoos);

void g()
{
std::vector<Foo> v;
...
f(v.empty() ? NULL : &v[0], v.size()); ↠safe
}

The funny expression v.empty() ? NULL : &v[0] simply passes the NULL
pointer if v is empty, otherwise passes a pointer to the first (zeroth)
element of v. If you know a priori that v is not empty, you can change
that to simply &v[0].
----------------------------

I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?
As I understand it if the vector is empty then any attempt to access any
element (in this case the first, at position 0) is passed the end of the
vector. Therefore this is undefined behaviour. This ternary operation
ensures that we never hit that situation.

Alan
 
R

red floyd

Numeromancer said:
The funny expression v.empty() ? NULL : &v[0] simply passes the NULL
pointer if v is empty, otherwise passes a pointer to the first (zeroth)
element of v. If you know a priori that v is not empty, you can change
that to simply &v[0].
----------------------------

I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?

It was corrected in TC1, that is, ISO/IEC 14882:2003 23.2.4/1

"The elements of a vector are stored contiguously, meaning that if
v is a vector<T, Allocator> where T is some type oher than bool, then it
obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size()."
 
R

red floyd

Gianni said:
Numeromancer wrote:
...

It is somthing ratified as errata I believe. I heard the next standard
will go as far as saying that basic_string is also contiguous.

I have no concrete reference other than postings by others.

Vector is contiguous as of TC1 aka the 2003 revision.
 
N

Numeromancer

Numeromancer said:
From the C++-FAQ Lite:

http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3

----------------------------
34.3] Is the storage for a std::vector<T> guaranteed to be contiguous?
Yes.

This means you the following technique is safe:

#include <vector>
#include "Foo.h" /* get class Foo */

// old-style code that wants an array
void f(Foo* array, unsigned numFoos);

void g()
{
std::vector<Foo> v;
...
f(v.empty() ? NULL : &v[0], v.size()); ↠safe
}

The funny expression v.empty() ? NULL : &v[0] simply passes the NULL
pointer if v is empty, otherwise passes a pointer to the first (zeroth)
element of v. If you know a priori that v is not empty, you can change
that to simply &v[0].
----------------------------

I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?

Thanks,

Tim S.

Thanks to those whose pointed to the TRs, I found it. I confess: I
thought that the author of the FAQ list was being chummy, :)humble but I
was wrong). I'm glad I asked. I'll be reading over TR1 carefully
henceforth.


Tim S.
 
R

red floyd

Numeromancer said:
The funny expression v.empty() ? NULL : &v[0] simply passes the NULL
pointer if v is empty, otherwise passes a pointer to the first
(zeroth) element of v. If you know a priori that v is not empty, you
can change that to simply &v[0].
----------------------------

I can find nothing in the standard to justify this statement. Does
anyone know the section in the standard (if any) which justifies this
statement?

Thanks,

Tim S.

Thanks to those whose pointed to the TRs, I found it. I confess: I
thought that the author of the FAQ list was being chummy, :)humble but I
was wrong). I'm glad I asked. I'll be reading over TR1 carefully
henceforth.

That's TC1 (Technical Corrigendum 1), not TR1.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,619
Members
45,312
Latest member
Svsdvsdvs

Latest Threads

Top