Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Double increment question.

Reply
Thread Tools

Double increment question.

 
 
Robbie Hatley
Guest
Posts: n/a
 
      07-25-2006
Hello, group. I've been doing too much C++ programming lately, and
I'm starting to become rusty at some aspects of the C way of doing
things, esp. efficient low-level data copies.

Specificially, I just wrote the following, but I don't know if this
is safe:

void Func(char* left, char* right)
{
chat temp_left [17] = {'\0'};
chat temp_right [17] = {'\0'};
int i;
char *ptr1, *ptr2;

/* ... do some stuff ... */

/* Copy the left part to temp_left: */
ptr1 = temp_left;
ptr2 = left;
while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???

/* ... do some other stuff ... */

return;
}

I'm pretty sure that's a conceptually sound way of copying the characters
starting at address "left", up-to-but-not-including address "right",
to array "temp_left".

But my question is, will I get into trouble with that double increment?
Is it guaranteed that (*ptr2) will always get assigned to (*ptr1) before
either increment occurs???

Sorry if this seems like a dorky question. I'm rusty.

--
Cheers,
Robbie Hatley
East Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
home dot pac bell dot net slant earnur slant


 
Reply With Quote
 
 
 
 
Richard Riley
Guest
Posts: n/a
 
      07-25-2006
"Robbie Hatley" <(E-Mail Removed)> writes:

> Hello, group. I've been doing too much C++ programming lately, and
> I'm starting to become rusty at some aspects of the C way of doing
> things, esp. efficient low-level data copies.
>


> while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???


> Is it guaranteed that (*ptr2) will always get assigned to (*ptr1) before
> either increment occurs???


Yes. Same as in C++ when dealing with char pointers isnt it?
 
Reply With Quote
 
 
 
 
spibou@gmail.com
Guest
Posts: n/a
 
      07-25-2006
Robbie Hatley wrote:

> Hello, group. I've been doing too much C++ programming lately, and
> I'm starting to become rusty at some aspects of the C way of doing
> things, esp. efficient low-level data copies.
>
> Specificially, I just wrote the following, but I don't know if this
> is safe:
>
> void Func(char* left, char* right)
> {
> chat temp_left [17] = {'\0'};
> chat temp_right [17] = {'\0'};
> int i;
> char *ptr1, *ptr2;
>
> /* ... do some stuff ... */
>
> /* Copy the left part to temp_left: */
> ptr1 = temp_left;
> ptr2 = left;
> while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???
>
> /* ... do some other stuff ... */
>
> return;
> }
>
> I'm pretty sure that's a conceptually sound way of copying the characters
> starting at address "left", up-to-but-not-including address "right",
> to array "temp_left".


I assume chat was meant to be char. I assume also i is used
in the part of the code not given.

> But my question is, will I get into trouble with that double increment?
> Is it guaranteed that (*ptr2) will always get assigned to (*ptr1) before
> either increment occurs???


Strictly speaking , what is guaranteed is that the location ptr2 points
to
before the increment will be assigned the value from the location ptr1
points to before the increment. But whether this assignment occurs
before the pointers have been inceremented is up to the implementation.

Spiros Bousbouras

 
Reply With Quote
 
BubbaGump
Guest
Posts: n/a
 
      07-25-2006
On Tue, 25 Jul 2006 03:31:33 GMT, "Robbie Hatley"
<(E-Mail Removed)> wrote:

>Hello, group. I've been doing too much C++ programming lately, and
>I'm starting to become rusty at some aspects of the C way of doing
>things, esp. efficient low-level data copies.
>
>Specificially, I just wrote the following, but I don't know if this
>is safe:
>
>void Func(char* left, char* right)
>{
> chat temp_left [17] = {'\0'};
> chat temp_right [17] = {'\0'};
> int i;
> char *ptr1, *ptr2;
>
> /* ... do some stuff ... */
>
> /* Copy the left part to temp_left: */
> ptr1 = temp_left;
> ptr2 = left;
> while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???
>
> /* ... do some other stuff ... */
>
> return;
>}
>
>I'm pretty sure that's a conceptually sound way of copying the characters
>starting at address "left", up-to-but-not-including address "right",
>to array "temp_left".
>
>But my question is, will I get into trouble with that double increment?
>Is it guaranteed that (*ptr2) will always get assigned to (*ptr1) before
>either increment occurs???
>
>Sorry if this seems like a dorky question. I'm rusty.



You find breaking up the operations into a form that's more obvious to
be objectionable?

while (ptr2 < right) {
*ptr1 = *ptr2;
ptr1++;
ptr2++;
}

 
Reply With Quote
 
Robbie Hatley
Guest
Posts: n/a
 
      07-25-2006
"Richard Riley" wrote:

> "Robbie Hatley" <(E-Mail Removed)> writes:
>
> > Hello, group. I've been doing too much C++ programming lately, and
> > I'm starting to become rusty at some aspects of the C way of doing
> > things, esp. efficient low-level data copies:
> > while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???
> > Is it guaranteed that (*ptr2) will always get assigned to (*ptr1) before
> > either increment occurs???

>
> Yes.


Thanks.

> Same as in C++ when dealing with char pointers isnt it?


If it works that way with the one, I suppose it does with the
other. However, my usual way of coping strings in C++ is:

std::string str1 ("Fred"); // make string str1 containing "Fred"
std::string str2 (str1); // make string str2 and copy str1 to str2

A bit simpler than in C.

--
Cheers,
Robbie Hatley
East Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
home dot pac bell dot net slant earnur slant


 
Reply With Quote
 
Robbie Hatley
Guest
Posts: n/a
 
      07-25-2006
<(E-Mail Removed)> wrote:

> Robbie Hatley wrote:
>
> > Hello, group. I've been doing too much C++ programming lately, and
> > I'm starting to become rusty at some aspects of the C way of doing
> > things, esp. efficient low-level data copies.
> >
> > Specificially, I just wrote the following, but I don't know if this
> > is safe:
> >
> > void Func(char* left, char* right)
> > {
> > chat temp_left [17] = {'\0'};
> > chat temp_right [17] = {'\0'};
> > int i;
> > char *ptr1, *ptr2;
> >
> > /* ... do some stuff ... */
> >
> > /* Copy the left part to temp_left: */
> > ptr1 = temp_left;
> > ptr2 = left;
> > while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???
> >
> > /* ... do some other stuff ... */
> >
> > return;
> > }
> >
> > I'm pretty sure that's a conceptually sound way of copying the characters
> > starting at address "left", up-to-but-not-including address "right",
> > to array "temp_left".

>
> I assume chat was meant to be char. I assume also i is used
> in the part of the code not given.


I was typing an excerpt from a larger function. I should have used
copy-'n'-paste instead, then deleted the excess junk. (The "chat" was
actually in the original, though. I'd not tried to compile it yet,
because I was worried about the run-time effects of the increments.)

> > But my question is, will I get into trouble with that double increment?
> > Is it guaranteed that (*ptr2) will always get assigned to (*ptr1) before
> > either increment occurs???

>
> Strictly speaking , what is guaranteed is that the location ptr2
> points to before the increment will be assigned the value from the
> location ptr1 points to before the increment. But whether this
> assignment occurs before the pointers have been inceremented is up
> to the implementation.


That's the important thing. As long as stuff is copied from the
correct source locations to the correct destination locations, all
is well.

--
Cheers,
Robbie Hatley
East Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
home dot pac bell dot net slant earnur slant


 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      07-25-2006
BubbaGump wrote:
> On Tue, 25 Jul 2006 03:31:33 GMT, "Robbie Hatley"
> <(E-Mail Removed)> wrote:


<snip>

>> while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???


<snip>

> You find breaking up the operations into a form that's more obvious to
> be objectionable?
>
> while (ptr2 < right) {
> *ptr1 = *ptr2;
> ptr1++;
> ptr2++;
> }


The code posted by Robbie Hatley is idiomatic C, so whether you like it
or not to be competent you have to understand it.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      07-25-2006
Robbie Hatley said:

> Hello, group. I've been doing too much C++ programming lately, and
> I'm starting to become rusty at some aspects of the C way of doing
> things, esp. efficient low-level data copies.
>
> Specificially, I just wrote the following, but I don't know if this
> is safe:


It isn't, but perhaps not for the reason you imagine.

> void Func(char* left, char* right)
> {
> chat temp_left [17] = {'\0'};
> chat temp_right [17] = {'\0'};
> int i;
> char *ptr1, *ptr2;
>
> /* ... do some stuff ... */
>
> /* Copy the left part to temp_left: */
> ptr1 = temp_left;
> ptr2 = left;
> while (ptr2 < right)


This comparison compares the ptr2 pointer value with a pointer to a
completely different object. Bad idea, unless you know for sure (and how
can you?) that 'right' is actually a pointer into the same object that
'left' points to.


> *ptr1++ = *ptr2++; // WILL THIS WORK???


Yes, because ptr1 and ptr2 do not at any time point to the same char. But
even so, wouldn't it be easier to work out how many bytes you want to copy
and just memcpy them?

> I'm pretty sure that's a conceptually sound way


Yes...

> of copying the characters starting at address "left",


....and yes...

> up-to-but-not-including address "right",


....and no, unless you can guarantee that 'right' points into the same
object.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      07-25-2006
BubbaGump wrote:

> On Tue, 25 Jul 2006 03:31:33 GMT, "Robbie Hatley"
> <(E-Mail Removed)> wrote:


(fx:snip)

>> while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???


(fx:snip)

> You find breaking up the operations into a form that's more obvious to
> be objectionable?
>
> while (ptr2 < right) {
> *ptr1 = *ptr2;
> ptr1++;
> ptr2++;
> }


I find the former more obvious than the latter. It's idiomatic, it's
presented compactly enough to see it as a unit, and it's harder to make
the mistake of incrementing the wrong variable or forgetting to
increment a variable.

I'm not really worried about code being inobvious to people who
are new to the language: not all code is suitable for tutorial
use.

The second form is more /explicit/, certainly.

--
Chris "or /tedious/" Dollin
This .signature temporarily left blank.

 
Reply With Quote
 
Robbie Hatley
Guest
Posts: n/a
 
      07-25-2006

<BubbaGump> wrote:

> Robbie Hatley wrote:
>
> > while (ptr2 < right) *ptr1++ = *ptr2++; // WILL THIS WORK???

>
> You find breaking up the operations into a form that's more
> obvious to be objectionable?
>
> while (ptr2 < right) {
> *ptr1 = *ptr2;
> ptr1++;
> ptr2++;
> }


A few years ago, I would have preferred that, yes. These days,
however, something like:

while (ptr2 < right) *ptr1++ = *ptr2++;

actually looks more "obvious" to me. At least, I understand the intent
of the author instantly. Whether or not the sequence points work out
right in such code is a different matter! It's so easy to make blunders
like that. But my friend Ron, the firmware guru, uses code like that
all the time without having it blow up on him. A matter of experience.

I was just googling "sequence point", trying to find more info on this,
and I ran across http://c-faq.com/ which is, lo and behold, the FAQ for
this group. That site mentions the following two sentences from the
C standard:

Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be accessed
only to determine the value to be stored.

After staring at those for a while I think I understand them.
If I'm getting the idea right, it says:

1. You aren't supposed to alter the same variable twice between
sequence points.
2. If you alter a variable between two sequence points, you're
not supposed to use the original value of that variable for
any purpose other than computing the final value to be stored
back into the variable.

For example, I think the following violates those rules:

int main()
{
int y=0;
int x=7;
y = 2*x + x++; // violates sentence 2?
printf("y = %d", y); // prints 21? or 22?

y=0;
x=7;
y = x++ + x++; // violates sentences 1 and 2?
printf("y = %d", y); // prints 14? or 15?

return 0;
}

Looks to me like both of those calculations are undefined.
Do I have that right?

--
Cheers,
Robbie Hatley
East Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
home dot pac bell dot net slant earnur slant


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Post increment ++ has higher precedence than pre increment ++. Why? Alf P. Steinbach /Usenet C++ 0 05-22-2011 12:03 PM
why prefix increment is faster than postfix increment? jrefactors@hotmail.com C++ 99 06-11-2010 12:51 PM
post increment or pre increment? Peng Yu Perl Misc 7 11-23-2008 11:44 PM
why prefix increment is faster than postfix increment? jrefactors@hotmail.com C Programming 104 10-27-2005 11:44 PM
cannot convert parameter from 'double (double)' to 'double (__cdecl *)(double)' error Sydex C++ 12 02-17-2005 06:30 PM



Advertisments