Simultaneous read and write on a variable in C++

P

Prasoon Saurav

On 12/01/2012 19:18, Prasoon Saurav wrote:
On 12/01/2012 18:11, Prasoon Saurav wrote:
On 1/11/2012 12:28 PM, Victor Bazarov wrote:
On 1/11/2012 12:08 PM, Novice Coder wrote:
Here is the code
int main()
{
char *p;
char a[]={"Hello"};
(p=a)[0]; // This line
return 0;
}
Is the behaviour of this code undefined in C++?
Yes, AFAIK. There is no intervening sequence point between the
assignment and indexing. Even though there are parentheses, it
is not
guaranteed that the compiler isn't going to "optimize" it and
use the
previous value of 'p' (undefined) for dereferencing it.
I think now that I was wrong there. The expression in parentheses
has
the value the same as 'a', and *that* is used to dereference the
pointer
(the indexing is adding the index and then dereferencing). The
relevant
portion of the Standard (using the latest Draft):
<<The assignment operator (=) and the compound assignment
operators all
group right-to-left. All require a modifiable lvalue as their left
operand and return an lvalue referring to the left operand. The
result
in all cases is a bit-field if the left operand is a bit-field.
In all
cases, the assignment is sequenced after the value computation of
the
right and left operands, and before the value computation of the
assignment expression.>>
The last sentence is important, I believe. "Sequenced" is the key
word.
If you need to
introduce a sequence point, use the comma:
p=a,p[0]; // no problem
V
V
--
I do not respond to top-posted replies, please don't ask
The term sequenced before/after and value computation are part of C+
+11 and not of C++03. In C++11 the expression has well defined
behavior. In C++03 it is not.
Nonsense.
(p=a)[0] is perfectly fine in C++03 as is *(p=a) as is *++p2; you are
confusing this defined behaviour with ((p=a)[0] + (p=a+1)[0]) which
is UB.
/Leigh
Instead of using words like "bullshit", "nonsense" why don't you take
help of the Standard to prove yourself correct. Which statement of
mine do you think is incorrect and why? If you have some counter-
argument please make it.
You said '*--p' is UB which disagrees with the draft standard:
24.4.1/5
"...
*first++ = *--last;
..."
So you clearly do not know what you are talking about in this area and I
still suspect you of being a troll.
/Leigh
One more thing whether *--p; invokes UB or not depends on whether 'p'
is a user defined type or not.
C++03
*--p; if p is a user defined type with overloaded -- and * then the
behavior is well defined (function calls introduce sequence points).
For primitive types like what we have in the opening post the behavior
is undefined.
In this case the example from the standard is for an iterator which can
be a pointer (i.e. a primitive type) so you are still wrong.

Aside: I can find many instances of *++p and *--p in Microsoft's
implementation of the C++ standard library.

So if you are to be believed the C++ standard is wrong; Microsoft is
wrong and the seminal "The C Programming Language" is wrong.

Admit you are wrong and move on.

/Leigh

I already said that the behavior is only undefined in C++03. It is
fine in C, I have given the reason why. It is fine in C++11, Victor
already gave the reason.

Yes C++03 standard had many defects, don't you know? :p This might be
one of them. No comments on Microsoft's implementation. The C
Programming Language is correct.
 
P

Prasoon Saurav

On 12/01/2012 19:46, Leigh Johnston wrote:
On 12/01/2012 19:44, Prasoon Saurav wrote:
On 12/01/2012 19:18, Prasoon Saurav wrote:
On 12/01/2012 18:11, Prasoon Saurav wrote:
On 1/11/2012 12:28 PM, Victor Bazarov wrote:
On 1/11/2012 12:08 PM, Novice Coder wrote:
Here is the code
int main()
{
char *p;
char a[]={"Hello"};
(p=a)[0]; // This line
return 0;
}
Is the behaviour of this code undefined in C++?
Yes, AFAIK. There is no intervening sequence point between the
assignment and indexing. Even though there are parentheses, it
is not
guaranteed that the compiler isn't going to "optimize" it and
use the
previous value of 'p' (undefined) for dereferencing it.
I think now that I was wrong there. The expression in parentheses
has
the value the same as 'a', and *that* is used to dereference the
pointer
(the indexing is adding the index and then dereferencing). The
relevant
portion of the Standard (using the latest Draft):
<<The assignment operator (=) and the compound assignment
operators all
group right-to-left. All require a modifiable lvalue as their left
operand and return an lvalue referring to the left operand. The
result
in all cases is a bit-field if the left operand is a bit-field.
In all
cases, the assignment is sequenced after the value computation of
the
right and left operands, and before the value computation of the
assignment expression.>>
The last sentence is important, I believe. "Sequenced" is the key
word.
If you need to
introduce a sequence point, use the comma:
p=a,p[0]; // no problem
V
V
--
I do not respond to top-posted replies, please don't ask
The term sequenced before/after and value computation are part of C+
+11 and not of C++03. In C++11 the expression has well defined
behavior. In C++03 it is not.
Nonsense.
(p=a)[0] is perfectly fine in C++03 as is *(p=a) as is *++p2;you are
confusing this defined behaviour with ((p=a)[0] + (p=a+1)[0])which
is UB.
/Leigh
Instead of using words like "bullshit", "nonsense" why don't you take
help of the Standard to prove yourself correct. Which statement of
mine do you think is incorrect and why? If you have some counter-
argument please make it.
You said '*--p' is UB which disagrees with the draft standard:
24.4.1/5
"...
*first++ = *--last;
..."
So you clearly do not know what you are talking about in this area and I
still suspect you of being a troll.
/Leigh
One more thing whether *--p; invokes UB or not depends on whether 'p'
is a user defined type or not.
C++03
*--p; if p is a user defined type with overloaded -- and * then the
behavior is well defined (function calls introduce sequence points).
For primitive types like what we have in the opening post the behavior
is undefined.
In this case the example from the standard is for an iterator which can
be a pointer (i.e. a primitive type) so you are still wrong.
Aside: I can find many instances of *++p and *--p in Microsoft's
implementation of the C++ standard library.
So if you are to be believed the C++ standard is wrong; Microsoft is
wrong and the seminal "The C Programming Language" is wrong.
Admit you are wrong and move on.
/Leigh
I already said that the behavior is only undefined in C++03. It is
fine in C, I have given the reason why. It is fine in C++11, Victor
already gave the reason.
Yes C++03 standard had many defects, don't you know? :p This might be
one of them. No comments on Microsoft's implementation. The C
Programming Language is correct.

You are a troll for sure; gtfo.

/Leigh

I used to troll at stackoverflow(here is my trolling profile:
http://stackoverflow.com/users/165520/prasoon-saurav) and now I am
trolling here. :) Now just stfu.

P.S
 
V

Victor Bazarov

Prasoon Saurav said:
The result of (p=a) is lvalue 'p' with its rvalue 'a'.

"The result of the assignment operation is the value stored in the left
operand _after the assignment has taken place_; the result is an
lvalue." [C++ standard : expr.ass]

Thank you, Gareth. ^5

V
 
J

Juha Nieminen

Leigh Johnston said:
So you clearly do not know what you are talking about in this area and I
still suspect you of being a troll.

Could you please stop using that word to mean "disagrees with me"?
You are approaching the same level of stupidity as paul.
 
N

Nick Keighley

Here is the code
int main()
{
    char *p;
    char a[]={"Hello"};
    (p=a)[0]; // This line
    return 0;

Is the behaviour of this code undefined in C++?

(p=a)[0]; is UB . The side effect of the assignment operation is
guaranteed to be complete only after we reach a sequence point i.e ' ;

why?

consider

while ((p = f (x, y)) == 0)

a fairly common C/C++ idiom. Yet you claim it won't work.
 
G

Goran

Here is the code
int main()
{
    char *p;
    char a[]={"Hello"};
    (p=a)[0]; // This line
    return 0;

Is the behaviour of this code undefined in C++?

(p=a)[0]; is UB . The side effect of the assignment operation is
guaranteed to be complete only after we reach a sequence point i.e ' ;
'. In this case the access is made prior to the side effect
completion. The is no total ordering between the assignment and the
dereference

You're looking at this the wrong way. The assignment to "p" does not
matter. The result of "=a" is some lvalue of type char*. It might, or
not, be "p" (as lvalue). That is what is being indexed with 0, not
necessarily "p". "p" might, or might not, have it's value assigned by
the time we reach sequence point, but that is completely irrelevant.

Goran.
 
P

Prasoon Saurav

Here is the code
int main()
{
    char *p;
    char a[]={"Hello"};
    (p=a)[0]; // This line
    return 0;
}
Is the behaviour of this code undefined in C++?
(p=a)[0]; is UB . The side effect of the assignment operation is
guaranteed to be complete only after we reach a sequence point i.e ' ;
'. In this case the access is made prior to the side effect
completion. The is no total ordering between the assignment and the
dereference

You're looking at this the wrong way. The assignment to "p" does not
matter. The result of "=a" is some lvalue of type char*. It might, or
not, be "p" (as lvalue). That is what is being indexed with 0, not
necessarily "p". "p" might, or might not, have it's value assigned by
the time we reach sequence point, but that is completely irrelevant.

Goran.

Yes now I understand why I was wrong. Thanks!

Here is a related link : http://stackoverflow.com/questions/8845569/is-p-actually-legalwell-formed-in-c03
 
B

BCFD36

Here is the code

int main()
{
char *p;
char a[]={"Hello"};
(p=a)[0]; // This line
return 0;
}

Is the behaviour of this code undefined in C++?

I read the whole thread. I'll never get those minutes back. Whether or
not it is well defined is not relevant except maybe in an academic
sense. The code is crap. Posit that it is well defined. So what. It is
obscure. It is opaque. There are other ways to make it clearer what you
want to do. This looks like something designed to try to break the compiler.

Just because something is legal, well defined, and you saw it somewhere
doesn't make it a good idea.
 

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

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,997
Latest member
mileyka

Latest Threads

Top