Hello everyone,


Suppose we defined a string buffer (array), like this,

char array[] = "hello world";
char buf[256]

Sometimes, I noticed that we either use,

1. array (buf)
or use,
2. &array (&buf)
or use
3. &array[0] (&buf[0])

as the beginning address of the array,

example like,

strcpy (buf, array);
strcpy (&buf, array);
...

I am wondering the differences between the 3 approaches, and which approach
is the most correct?


thanks in advance,
George

Re: string buffer by Igor

Igor
Mon Dec 10 04:57:34 PST 2007

"George" <George@discussions.microsoft.com> wrote in message
news:C8D3791E-5B02-49AB-8589-88CACF2F6861@microsoft.com
> Suppose we defined a string buffer (array), like this,
>
> char array[] = "hello world";
> char buf[256]
>
> Sometimes, I noticed that we either use,
>
> 1. array (buf)
> or use,
> 2. &array (&buf)
> or use
> 3. &array[0] (&buf[0])
>
> as the beginning address of the array,

All three are equivalent most of the time, resulting in the pointer to
the first element of the array. There are exceptions: e.g. sizeof(buf)
gives the size of the array (256 in your example), but sizeof(&buf) and
sizeof(&buf[0]) return the size of the pointer (4 on 32-bit systems).

Using just plain "buf" is most common. Less typing for the same result.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: string buffer by Tom

Tom
Mon Dec 10 08:48:46 PST 2007

George wrote:
> Hello everyone,
>
>
> Suppose we defined a string buffer (array), like this,
>
> char array[] = "hello world";
> char buf[256]
>
> Sometimes, I noticed that we either use,
>
> 1. array (buf)

The name of an array decays to a pointer to the first element (the
pointer has type char* in this case), except when used in certain
contexts, such as binding to a reference or in a sizeof

> or use,
> 2. &array (&buf)

That takes the address of the array (which is numerically the same
pointer value as the address of the first element), which has type: char
(*)[12] in the first case and char (*)[256] in the second.

> or use
> 3. &array[0] (&buf[0])

This is identical to 1, except where pointer decay doesn't apply to 1.

> as the beginning address of the array,
>
> example like,
>
> strcpy (buf, array);
> strcpy (&buf, array);

The second shouldn't compile, since strcpy requires a char*. &buf[0]
will compile, but it's usual to use just buf where possible, such as here.

Tom

Re: string buffer by Norbert

Norbert
Mon Dec 10 13:34:53 PST 2007


Tom Widmer [VC++ MVP] schrieb:
> George wrote:
>> Hello everyone,
>>
>>
>> Suppose we defined a string buffer (array), like this,
>>
>> char array[] = "hello world";
>> char buf[256]
>>
>> Sometimes, I noticed that we either use,
>>
>> 1. array (buf)
>
> The name of an array decays to a pointer to the first element (the
> pointer has type char* in this case), except when used in certain
> contexts, such as binding to a reference or in a sizeof
>
>> or use,
>> 2. &array (&buf)
>
> That takes the address of the array (which is numerically the same
> pointer value as the address of the first element), which has type: char
> (*)[12] in the first case and char (*)[256] in the second.
>
>> or use
>> 3. &array[0] (&buf[0])
>
> This is identical to 1, except where pointer decay doesn't apply to 1.

In this particular case, you are right. But in general, you should not assume
that "buf" is the same as "&buf[0]". If some time later some maintainer decides
it would be nice to replace buf[256] by the more robust std::vector<char> then
you get:

1. buf: the vector<byte> object
2. &buff: The address of (pointer to) the vector<byte> object
3. &buff[0]: pointer to the first element (the string)

So &buff[0] would mean the same in both cases. I am not sure if tht is also true
for std::string...

Norbert



Re: string buffer by George

George
Mon Dec 10 19:27:01 PST 2007

Hi Tom,


> > strcpy (buf, array);
> > strcpy (&buf, array);
>
> The second shouldn't compile, since strcpy requires a char*. &buf[0]
> will compile, but it's usual to use just buf where possible, such as here.
>

Both can compile in C, but only the 1st one can compiler in C++. In C, both
buf and &buf have the same value, and this is why I am most confused. Why a
variable is the same as the pointer of it?


regards,
George

"Tom Widmer [VC++ MVP]" wrote:

> George wrote:
> > Hello everyone,
> >
> >
> > Suppose we defined a string buffer (array), like this,
> >
> > char array[] = "hello world";
> > char buf[256]
> >
> > Sometimes, I noticed that we either use,
> >
> > 1. array (buf)
>
> The name of an array decays to a pointer to the first element (the
> pointer has type char* in this case), except when used in certain
> contexts, such as binding to a reference or in a sizeof
>
> > or use,
> > 2. &array (&buf)
>
> That takes the address of the array (which is numerically the same
> pointer value as the address of the first element), which has type: char
> (*)[12] in the first case and char (*)[256] in the second.
>
> > or use
> > 3. &array[0] (&buf[0])
>
> This is identical to 1, except where pointer decay doesn't apply to 1.
>
> > as the beginning address of the array,
> >
> > example like,
> >
> > strcpy (buf, array);
> > strcpy (&buf, array);
>
> The second shouldn't compile, since strcpy requires a char*. &buf[0]
> will compile, but it's usual to use just buf where possible, such as here.
>
> Tom
>

Re: string buffer by George

George
Mon Dec 10 19:28:00 PST 2007

Yes Norbert,


I agree STL is better, but I have to maintain some old code. :-)


regards,
George

"Norbert Unterberg" wrote:

>
> Tom Widmer [VC++ MVP] schrieb:
> > George wrote:
> >> Hello everyone,
> >>
> >>
> >> Suppose we defined a string buffer (array), like this,
> >>
> >> char array[] = "hello world";
> >> char buf[256]
> >>
> >> Sometimes, I noticed that we either use,
> >>
> >> 1. array (buf)
> >
> > The name of an array decays to a pointer to the first element (the
> > pointer has type char* in this case), except when used in certain
> > contexts, such as binding to a reference or in a sizeof
> >
> >> or use,
> >> 2. &array (&buf)
> >
> > That takes the address of the array (which is numerically the same
> > pointer value as the address of the first element), which has type: char
> > (*)[12] in the first case and char (*)[256] in the second.
> >
> >> or use
> >> 3. &array[0] (&buf[0])
> >
> > This is identical to 1, except where pointer decay doesn't apply to 1.
>
> In this particular case, you are right. But in general, you should not assume
> that "buf" is the same as "&buf[0]". If some time later some maintainer decides
> it would be nice to replace buf[256] by the more robust std::vector<char> then
> you get:
>
> 1. buf: the vector<byte> object
> 2. &buff: The address of (pointer to) the vector<byte> object
> 3. &buff[0]: pointer to the first element (the string)
>
> So &buff[0] would mean the same in both cases. I am not sure if tht is also true
> for std::string...
>
> Norbert
>
>
>

Re: string buffer by George

George
Mon Dec 10 19:29:01 PST 2007

Thanks Igor,


Your experience and advice are cool.


regards,
George

"Igor Tandetnik" wrote:

> "George" <George@discussions.microsoft.com> wrote in message
> news:C8D3791E-5B02-49AB-8589-88CACF2F6861@microsoft.com
> > Suppose we defined a string buffer (array), like this,
> >
> > char array[] = "hello world";
> > char buf[256]
> >
> > Sometimes, I noticed that we either use,
> >
> > 1. array (buf)
> > or use,
> > 2. &array (&buf)
> > or use
> > 3. &array[0] (&buf[0])
> >
> > as the beginning address of the array,
>
> All three are equivalent most of the time, resulting in the pointer to
> the first element of the array. There are exceptions: e.g. sizeof(buf)
> gives the size of the array (256 in your example), but sizeof(&buf) and
> sizeof(&buf[0]) return the size of the pointer (4 on 32-bit systems).
>
> Using just plain "buf" is most common. Less typing for the same result.
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>

Re: string buffer by Carl

Carl
Tue Dec 11 07:52:48 PST 2007

George wrote:
> Hi Tom,
>
>
>>> strcpy (buf, array);
>>> strcpy (&buf, array);
>>
>> The second shouldn't compile, since strcpy requires a char*. &buf[0]
>> will compile, but it's usual to use just buf where possible, such as
>> here.
>>
>
> Both can compile in C, but only the 1st one can compiler in C++.

Simple - C has a weaker type system than C++.

> In
> C, both buf and &buf have the same value, and this is why I am most
> confused. Why a variable is the same as the pointer of it?

Because that's what the language standard says?

Fundamentally, it's because C (and, to a somewhat lesser extent, C++)
doesn't really have an array type. Rather, C lets you treat a block of
memory as an array of like-typed objects. But at it's core, C knows that
you're just working with pointers to blocks of memory, so the implicit
conversion was allowed.

Keep in mind that C was not designed for beginers to use - it was designed
for engineers that know assembly language and hardware architectures to be
more productive than they would be using assembly while lifting the code up
to a just slightly more abstract representation that could be hardware
independent. With that pedigree, it's full of gotchas and dark corners.
C++ solved some of those gotchas, but then added a whole collection of its
own.

-cd



Re: string buffer by Tom

Tom
Tue Dec 11 09:50:20 PST 2007

Norbert Unterberg wrote:

> In this particular case, you are right. But in general, you should not
> assume that "buf" is the same as "&buf[0]". If some time later some
> maintainer decides it would be nice to replace buf[256] by the more
> robust std::vector<char> then you get:
>
> 1. buf: the vector<byte> object
> 2. &buff: The address of (pointer to) the vector<byte> object
> 3. &buff[0]: pointer to the first element (the string)
>
> So &buff[0] would mean the same in both cases. I am not sure if tht is
> also true for std::string...

std::string isn't necessarily contiguous (though it is in all existing
implementations), so you shouldn't really use it with strcpy. In
general, I think I'd prefer the compiler errors when switching away from
char*, to force suitable code review.

Tom

Re: string buffer by George

George
Wed Dec 12 00:13:02 PST 2007

Thanks for your advice, cd!


regards,
George

"Carl Daniel [VC++ MVP]" wrote:

> George wrote:
> > Hi Tom,
> >
> >
> >>> strcpy (buf, array);
> >>> strcpy (&buf, array);
> >>
> >> The second shouldn't compile, since strcpy requires a char*. &buf[0]
> >> will compile, but it's usual to use just buf where possible, such as
> >> here.
> >>
> >
> > Both can compile in C, but only the 1st one can compiler in C++.
>
> Simple - C has a weaker type system than C++.
>
> > In
> > C, both buf and &buf have the same value, and this is why I am most
> > confused. Why a variable is the same as the pointer of it?
>
> Because that's what the language standard says?
>
> Fundamentally, it's because C (and, to a somewhat lesser extent, C++)
> doesn't really have an array type. Rather, C lets you treat a block of
> memory as an array of like-typed objects. But at it's core, C knows that
> you're just working with pointers to blocks of memory, so the implicit
> conversion was allowed.
>
> Keep in mind that C was not designed for beginers to use - it was designed
> for engineers that know assembly language and hardware architectures to be
> more productive than they would be using assembly while lifting the code up
> to a just slightly more abstract representation that could be hardware
> independent. With that pedigree, it's full of gotchas and dark corners.
> C++ solved some of those gotchas, but then added a whole collection of its
> own.
>
> -cd
>
>
>

Re: string buffer by George

George
Wed Dec 12 00:14:01 PST 2007

Thanks for sharing your points, Tom!


regards,
George

"Tom Widmer [VC++ MVP]" wrote:

> Norbert Unterberg wrote:
>
> > In this particular case, you are right. But in general, you should not
> > assume that "buf" is the same as "&buf[0]". If some time later some
> > maintainer decides it would be nice to replace buf[256] by the more
> > robust std::vector<char> then you get:
> >
> > 1. buf: the vector<byte> object
> > 2. &buff: The address of (pointer to) the vector<byte> object
> > 3. &buff[0]: pointer to the first element (the string)
> >
> > So &buff[0] would mean the same in both cases. I am not sure if tht is
> > also true for std::string...
>
> std::string isn't necessarily contiguous (though it is in all existing
> implementations), so you shouldn't really use it with strcpy. In
> general, I think I'd prefer the compiler errors when switching away from
> char*, to force suitable code review.
>
> Tom
>

Re: string buffer by Jeff

Jeff
Wed Dec 12 04:48:37 PST 2007

Carl Daniel [VC++ MVP] wrote:
> George wrote:
>> Hi Tom,
>> In
>> C, both buf and &buf have the same value, and this is why I am most
>> confused. Why a variable is the same as the pointer of it?
>
> Because that's what the language standard says?
>
> Fundamentally, it's because C (and, to a somewhat lesser extent, C++)
> doesn't really have an array type.

IIRC, this is available in C++ in TR1 with std::array based on boost::array.

Jeff