473,379 Members | 1,201 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,379 software developers and data experts.

Pointer Arithmetic Problem

#include <stdio.h>

int main( void )
{
char arrc[] = { 'a', 'b', 'c', '\0' };
char* pc = arrc;
char** ppc = &pc;

printf("arrc = %s\n", arrc);
printf("------------------------\n");
printf("*pc = %5c\n", *pc);
printf("**ppc = %5c\n", **ppc);
printf("++*pc = %5c, *pc = %5c\n", ++*pc, *pc);
printf("(**ppc)++ = %5c, **ppc = %5c\n", (**ppc)++, **ppc);
return 0;
}
===================== OUTPUT ==========================
[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra ok.c
[arnuld@dune ztest]$ ./a.out
arrc = abc
------------------------
*pc = a
**ppc = a
++*pc = b, *pc = a
(**ppc)++ = b, **ppc = b
[arnuld@dune ztest]$
I am little confused at the output. after ++*pc , the *pc should print
'b', not 'a'. Same for **ppc, which is again printing the same element
even after having gone through a ++.

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Gooogle Groups is Blocked. Reason: Excessive Spamming

Oct 3 '08 #1
16 1400
arnuld wrote:
#include <stdio.h>

int main( void )
{
char arrc[] = { 'a', 'b', 'c', '\0' };
char* pc = arrc;
char** ppc = &pc;

printf("arrc = %s\n", arrc);
printf("------------------------\n");
printf("*pc = %5c\n", *pc);
printf("**ppc = %5c\n", **ppc);
printf("++*pc = %5c, *pc = %5c\n", ++*pc, *pc);
printf("(**ppc)++ = %5c, **ppc = %5c\n", (**ppc)++, **ppc);
return 0;
}
===================== OUTPUT ==========================
[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra ok.c
[arnuld@dune ztest]$ ./a.out
arrc = abc
------------------------
*pc = a
**ppc = a
++*pc = b, *pc = a
(**ppc)++ = b, **ppc = b
[arnuld@dune ztest]$
I am little confused at the output. after ++*pc , the *pc should print
'b', not 'a'. Same for **ppc, which is again printing the same element
even after having gone through a ++.
Undefined behavoir in the last printf and I think in the 2nd to last too.
You modify ppc and look at it again without a squence point in between.

Bye, Jojo
Oct 3 '08 #2
jt
On Oct 3, 2:16*pm, "Joachim Schmitz" <nospam.j...@schmitz-digital.de>
wrote:
arnuld wrote:
#include <stdio.h>
int main( void )
{
*char arrc[] = { 'a', 'b', 'c', '\0' };
*char* pc = arrc;
*char** ppc = &pc;
*printf("arrc = %s\n", arrc);
*printf("------------------------\n");
*printf("*pc * * * = %5c\n", *pc);
*printf("**ppc * * = %5c\n", **ppc);
*printf("++*pc * * = %5c, *pc * = %5c\n", ++*pc, *pc);
*printf("(**ppc)++ = %5c, **ppc = %5c\n", (**ppc)++, **ppc);
*return 0;
}
===================== OUTPUT ==========================
[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra ok.c
[arnuld@dune ztest]$ ./a.out
arrc = abc
------------------------
*pc * * * = * * a
**ppc * * = * * a
++*pc * * = * * b, *pc * = * * a
(**ppc)++ = * * b, **ppc = * * b
[arnuld@dune ztest]$
I am little confused at the output. after ++*pc , the *pc should print
'b', not 'a'. Same for **ppc, which is again printing the same element
even after having gone through a ++.

Undefined behavoir in the last printf and I think in the 2nd to last too.
You modify ppc and look at it again without a squence point in between.

Bye, Jojo
hii...
after any function call the argumants are pushed on to a stack(i.e.
starting from left)...
and then they evaluated as they are popped..
so here the first argument to be evaluated is <*pcnot <++*pc>
since <++*pcis pre incrementation <agets incremented to <bin the
same statement...
in the next printf()...
the same thing happens, but since it is post incrementation...you wont
see the effect in this statement....
try adding another statement...maybe..
printf("\n\n **ppc= %c\n",**ppc);
..
..
you'll know the change....
hope this clears your doubt..
Oct 3 '08 #3
On Fri, 03 Oct 2008 17:31:23 -0700, Barry Schwarz wrote:
... SNIP...
Finally, the code invokes undefined behavior since between sequence
points *pc is modified but it is evaluated twice and for purposes
other than determining its new value.
What you mean by "for purposes other than determining its new value" ?
e.g. do you mean all I can do in single statement is to either print the
value of the variable or increment (or anything else like assigning th
vale to some array element) ?

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Gooogle Groups is Blocked. Reason: Excessive Spamming

Oct 4 '08 #4
arnuld <su*****@invalid.addresswrites:
>On Fri, 03 Oct 2008 17:31:23 -0700, Barry Schwarz wrote:
... SNIP...
Finally, the code invokes undefined behavior since between sequence
points *pc is modified but it is evaluated twice and for purposes
other than determining its new value.

What you mean by "for purposes other than determining its new value" ?
e.g. do you mean all I can do in single statement is to either print the
value of the variable or increment (or anything else like assigning th
vale to some array element) ?
Here's what the standard says:

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 read only to
determine the value to be stored.

A footnote says:

This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;

The point of the second part, "the prior value shall be read only to
determine the value to be stored" is that reading and writing the same
object is ok *if* the value that's read is used to compute the value
to be written, because that imposes an ordering. If the value that's
read isn't used to compute the value to be written, as in the right
hand side of "a[i++] = i;", then no such ordering is imposed, and
there's no single valid result. Rather than requiring a result that's
consistent with one of the valid orderings, the standard renders the
entire behavior undefined; this allows for more aggressive
optimization in some cases.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 4 '08 #5
Nick Keighley said:

<snip>
As someone (Bohr?) said "you're not right, you're not even wrong."
Well, not quite those exact words, but you're thinking of Wolfgang Pauli
(1900-1958).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 4 '08 #6
Thank yoy
Oct 4 '08 #7
On Sat, 04 Oct 2008 00:55:54 -0700, Keith Thompson <ks***@mib.org>
wrote:
>arnuld <su*****@invalid.addresswrites:
>>On Fri, 03 Oct 2008 17:31:23 -0700, Barry Schwarz wrote:
... SNIP...
Finally, the code invokes undefined behavior since between sequence
points *pc is modified but it is evaluated twice and for purposes
other than determining its new value.

What you mean by "for purposes other than determining its new value" ?
e.g. do you mean all I can do in single statement is to either print the
value of the variable or increment (or anything else like assigning th
vale to some array element) ?

Here's what the standard says:

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 read only to
determine the value to be stored.

A footnote says:

This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;

The point of the second part, "the prior value shall be read only to
determine the value to be stored" is that reading and writing the same
object is ok *if* the value that's read is used to compute the value
to be written, because that imposes an ordering. If the value that's
read isn't used to compute the value to be written, as in the right
hand side of "a[i++] = i;", then no such ordering is imposed, and
there's no single valid result. Rather than requiring a result that's
consistent with one of the valid orderings, the standard renders the
entire behavior undefined; this allows for more aggressive
optimization in some cases.
As a point of interest, the quoted section comes from 6.5-2 of n1256.
In n1336, the draft of the next standard (C09?), it has been
completely reworded:

"If a side effect on a scalar object is unsequenced relative to either
a different side effect on the same scalar object or a value
computation using the value of the same scalar object, the behavior is
undefined. If there are multiple allowable orderings of the
subexpressions of an expression, the behavior is undefined if such an
unsequenced side effect occurs in any of the orderings."

The footnote is unchanged.

The corresponding section of J.2 has been reworded in a similar
fashion.

--
Remove del for email
Oct 4 '08 #8
On Sat, 04 Oct 2008 00:55:54 -0700, Keith Thompson wrote:

Here's what the standard says:

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 read only to
determine the value to be stored.
This language feels like the language of High-Court notices to me. I still
don't understand the meaning of it. All I understand is this:
we can modify the value in a single expression, then we must not read
the vale either before or after the modification.
Does it mean that "one can expect a defined behavior, in one single expression, only if" :

1) he does ++*p and does not read its value before or after
this modification.

2) he does not modify at all but only read the value more than
1 time in a single expression.
Hence only these are defined behaviors:

printf("%d\n", ++*p); /* prints the incremented vale of *p */
printf("%d, %d, %d\n", *p, *p, *p);


A footnote says:

This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
both expressions are undefined. I don't see why standard used 2
expressions when one is enough.

while allowing
i = i + 1;
a[i] = i;
The point of the second part, "the prior value shall be read only to
determine the value to be stored"

but these are 2 different expressions.

is that reading and writing the same
object is ok *if* the value that's read is used to compute the value
to be written, because that imposes an ordering. If the value that's
read isn't used to compute the value to be written, as in the right
hand side of "a[i++] = i;", then no such ordering is imposed, and
there's no single valid result.

I got this one completely :)

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Gooogle Groups is Blocked. Reason: Excessive Spamming

Oct 6 '08 #9
On 4 Oct, 13:21, Richard Heathfield <r...@see.sig.invalidwrote:
Nick Keighley said:
As someone (Bohr?) said "you're not right, you're not even wrong."

Well, not quite those exact words, but you're thinking of Wolfgang Pauli
(1900-1958).
so it could be said of my statement
'That's not right. It's not even wrong'

and it was indeed Pauli

thanks

--
Nick Keighley
Oct 6 '08 #10
arnuld <su*****@invalid.addresswrites:
>On Sat, 04 Oct 2008 00:55:54 -0700, Keith Thompson wrote:
>Here's what the standard says:

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 read only to
determine the value to be stored.

This language feels like the language of High-Court notices to me. I still
don't understand the meaning of it. All I understand is this:
we can modify the value in a single expression, then we must not read
the vale either before or after the modification.
Um, not quite. You can certainly read and then modify the value of an
object with an expression; for example, "i = i + 1;" is ok.
Does it mean that "one can expect a defined behavior, in one single
expression, only if" :

1) he does ++*p and does not read its value before or after
this modification.

2) he does not modify at all but only read the value more than
1 time in a single expression.
Hence only these are defined behaviors:

printf("%d\n", ++*p); /* prints the incremented vale of *p */
printf("%d, %d, %d\n", *p, *p, *p);
I'm not sure I understand the question. Those certainly do have
well-defined behavior, but there are an infinite variety of other
expressions that also have well-defined behavior.
>A footnote says:

This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;

both expressions are undefined. I don't see why standard used 2
expressions when one is enough.
Because they demonstrate undefined behavior for two different reasons.
The first modifies the object "i" twice. The second reads and
modifies "i", but it's undefined because it reads i for a purpose
other than computing the value to store in it.
> while allowing
i = i + 1;
a[i] = i;
>The point of the second part, "the prior value shall be read only to
determine the value to be stored"

but these are 2 different expressions.
Huh? Do you mean that "i = i + 1;" and "a[i] = i;" are two different
expressions? Yes, they are (actually two different expression
statements). What's your point?
>is that reading and writing the same
object is ok *if* the value that's read is used to compute the value
to be written, because that imposes an ordering. If the value that's
read isn't used to compute the value to be written, as in the right
hand side of "a[i++] = i;", then no such ordering is imposed, and
there's no single valid result.


I got this one completely :)
Um, ok. Does the smiley mean you didn't get it, or am I just missing
the joke?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 6 '08 #11
arnuld <su*****@invalid.addresswrote:
On Sat, 04 Oct 2008 00:55:54 -0700, Keith Thompson wrote:
Here's what the standard says:

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 read only to
determine the value to be stored.

This language feels like the language of High-Court notices to me.
That may be because, like High Court judgements, they have to be exact,
lest someone notice the loopholes and starts abusing them.
I still don't understand the meaning of it. All I understand is this:

we can modify the value in a single expression, then we must not read
the vale either before or after the modification.
Until we hit the next sequence point. Yes.
Does it mean that "one can expect a defined behavior, in one single expression, only if" :
FSVO "expression", but...
1) he does ++*p and does not read its value before or after
this modification.

2) he does not modify at all but only read the value more than
1 time in a single expression.
....yes, and yes.
Hence only these are defined behaviors:

printf("%d\n", ++*p); /* prints the incremented vale of *p */
printf("%d, %d, %d\n", *p, *p, *p);
Yes. And similar ones, of course.
A footnote says:

This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;

both expressions are undefined. I don't see why standard used 2
expressions when one is enough.
More examples, more clarity. (Up to a reasonable point, of course.)

Richard
Oct 6 '08 #12
On Mon, 06 Oct 2008 00:42:42 -0700, Keith Thompson wrote:
>arnuld <su*****@invalid.addresswrites:
> we can modify the value in a single expression, then we must not read
the vale either before or after the modification.
Um, not quite. You can certainly read and then modify the value of an
object with an expression; for example, "i = i + 1;" is ok.
That I know, because there is stupidity revolving here like i = i++ + 1.
Huh? Do you mean that "i = i + 1;" and "a[i] = i;" are two different
expressions? Yes, they are (actually two different expression
statements). What's your point?

point is: If we put both of them in one expression, then we will stilll
have well-defined behavior, so why you used 2 expressions:

printf("values are: %d and %d\n", i = i + 1, a[i] = i);

its not UB.
Um, ok. Does the smiley mean you didn't get it, or am I just missing
the joke?
I was happy that I understood full of your paragraph when I don't
understand 50% of them on clc (because of pointer-business)

--
www.lispmachine.wordpress.com
my email is @ the above blog.
Oct 6 '08 #13
On Oct 6, 9:53 am, arnuld <sunr...@invalid.addresswrote:
On Mon, 06 Oct 2008 00:42:42 -0700, Keith Thompson wrote:
Huh? Do you mean that "i = i + 1;" and "a[i] = i;" are two different
expressions? Yes, they are (actually two different expression
statements). What's your point?

point is: If we put both of them in one expression, then we will stilll
have well-defined behavior, so why you used 2 expressions:

printf("values are: %d and %d\n", i = i + 1, a[i] = i);

its not UB.
Actually, that printf call *does* cause UB.
In the second argument, you modify the variable i and
in the third argument, you access (read) the variable i for another
reason than to calculate the new value of i.
As there is no sequence point between the evaluation of the two
arguments, the behaviour is undefined.

Bart v Ingen Schenau
Oct 6 '08 #14
In article <87************@bsb.me.uk>,
Ben Bacarisse <be********@bsb.me.ukwrote:
>Yes it is. If you find the legalese hard, I find the following
useful: if you can find two (or more) valid orders of execution that
give different results then the code is UB. I am not sure that this
always works but it seems, in practise, to be pretty useful.
Not only is that a good rule of thumb, but it explains *why* it's
undefined behaviour: different compilers may choose different orders,
or perhaps even interleave execution of the expressions.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Oct 6 '08 #15
arnuld <su*****@invalid.addresswrites:
>On Mon, 06 Oct 2008 00:42:42 -0700, Keith Thompson wrote:
>>arnuld <su*****@invalid.addresswrites:
>> we can modify the value in a single expression, then we must not read
the vale either before or after the modification.
>Um, not quite. You can certainly read and then modify the value of an
object with an expression; for example, "i = i + 1;" is ok.

That I know, because there is stupidity revolving here like i = i++ + 1.
Good, but the rule as you stated it above implies that "i = i + 1;" is
undefined.
>Huh? Do you mean that "i = i + 1;" and "a[i] = i;" are two different
expressions? Yes, they are (actually two different expression
statements). What's your point?

point is: If we put both of them in one expression, then we will stilll
have well-defined behavior, so why you used 2 expressions:

printf("values are: %d and %d\n", i = i + 1, a[i] = i);

its not UB.
Yes, it is. But even if it weren't, using two examples is clearer
than shoving the examples together into a single more complicated
expression.

[...]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 6 '08 #16
arnuld wrote:
[...]
point is: If we put both of them in one expression, then we will stilll
have well-defined behavior, so why you used 2 expressions:

printf("values are: %d and %d\n", i = i + 1, a[i] = i);

its not UB.
It *is* undefined behavior. Specifically, it both modifies `i'
(in `i = i + 1') and uses the value outside the modification itself
(in `a[i] = i') without an intervening sequence point. The commas
in the function argument list are not the comma operator, which
would introduce sequence points, but merely punctuation, which doesn't.

References: C99 6.5p2, FAQ 3.1 (and links to related questions).

--
Er*********@sun.com
Oct 6 '08 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Pushkar Pradhan | last post by:
I tried to read the archives and solve this problem, but now I think I better post my problem: int main() { int blkSz = { {2,2}, {2,3}, ....., {6,6} }; write_bc_perf(mflops1, blkSz,...
23
by: Ken Turkowski | last post by:
The construct (void*)(((long)ptr + 3) & ~3) worked well until now to enforce alignment of the pointer to long boundaries. However, now VC++ warns about it, undoubtedly to help things work on 64...
26
by: Alfonso Morra | last post by:
Hi, I'm getting a compiler error of "pointer truncation from 'void *' to 'int'" because I'm not explicitly casting from void* to (datatype*). Pointers are stored as ints (is that right?), so as...
6
by: Francois Grieu | last post by:
Are these programs correct ? #include <stdio.h> unsigned char a = {1,2}; int main(void) { unsigned char j; for(j=1; j<=2; ++j) printf("%u\n", *( a+j-1 )); return 0; }
27
by: Erik de Castro Lopo | last post by:
Hi all, The GNU C compiler allows a void pointer to be incremented and the behaviour is equivalent to incrementing a char pointer. Is this legal C99 or is this a GNU C extention? Thanks in...
26
by: Bill Reid | last post by:
Bear with me, as I am not a "professional" programmer, but I was working on part of program that reads parts of four text files into a buffer which I re-allocate the size as I read each file. I...
5
by: jdcrief | last post by:
I have all of this program working except for the pointer arithmetic part, I think. This program should average the student's grades together using pointer arithmetic and then display the...
2
by: guy.gorodish | last post by:
hi, i have couple of qeustions: 1. I have built a interop of c dll. In this dll i have a function that expect a pointer to a struct. I want to pass a struct from my c# interop into this c...
3
by: =?Utf-8?B?RGlwZXNoX1NoYXJtYQ==?= | last post by:
Hi all, I am porting my code in VC++ to VC.net i.e managed. I have seen somewhere that i need to convert my char* to String*, but String * doesnt perform pointer arithmetic like String* p; *p++='...
19
by: =?iso-8859-1?b?VG9t4XMg0yBoyWlsaWRoZQ==?= | last post by:
Coming originally from C++, I used to do the likes of the following, using a pointer in a conditional: void Func(int *p) { if (p) { *p++ = 7; *p++ = 8;
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.