Bit Pattern Problem

F

fb

William said:
So....that told you what the problem is?

I thought it might have...I was going to check it later, though at first
glance in did seem fine to me (assuming 8 bit bytes).
Watch out - you're hand waving it. I get the impression you
aren't trying to understand what the problem is, you are just
wanting someone to tell you what code to throw at the compiler.

umm...I don't want to admit that...but it's kinda true. I had been
staring at it for a while and gave up...posted this message and left.
Otherwise you should have asked what could possibly be wrong with
that line. It should work for you - but it is not robust and,
conceivably, might not work on your machine - and even if it did
have a problem it wouldn't yield the result you are experiencing.

But I'm not getting the impression that understanding the
relationship between your code and the results your code produce
is very high on your priority list.

I can't say that I cared at that point in time, though a good nights
sleep fixed that...I'll take a few breaths and think about it next time.

ciao.
 
M

Mac

Nice try invoking UD on signed shift, but mask is unsigned. It was
merely assigned from a signed variable, but I think that's well-defined
with two's-complement semantics. As an aside, in my experience, even
signed variable shifts typically get compiled into logical rather than
arithmetic shifts.

You are right that I was assuming mask was an int. I didn't mention UB,
though. I just quoted from the standard, and the part I quoted said
implementation defined. But since mask is unsigned, the part I quoted
(which you snipped) is irrelevant.

--Mac
 
B

Barry Schwarz

Chapter and verse, please.
I was going from n869 J.2 "Conversion to or from an integer type
produces a value outside the range that can be represented (6.3.1.4)."
but I see that applies only to floating to integer conversions and not
integer to integer. 6.3.1.3 covers integer to integer and specifies
implementation defined.


<<Remove the del for email>>
 
B

Barry Schwarz

Could someone please explain what section 6.5.16-4 means

"The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined."

I understand the order of evaluation part.

d = b*b-4*a*c;
if (d>0) ...

This is pretty common code and obviously not undefined behavior if the
variables are properly defined and assigned values. But it seems that
the if statement attempts to access the result of the previous
assignment operator after the end of statement sequence point as
described in the quote. What am I misinterpreting?


<<Remove the del for email>>
 
A

Arthur J. O'Dwyer

Could someone please explain what section 6.5.16-4 means

"The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined."

I understand the order of evaluation part.

d = b*b-4*a*c;
if (d>0) ...

This is pretty common code and obviously not undefined behavior if the
variables are properly defined and assigned values. But it seems that
the if statement attempts to access the result of the previous
assignment operator after the end of statement sequence point as
described in the quote. What am I misinterpreting?

The result of the assignment operator is discarded. It never gets
used. What gets used in the 'if' statement is the value of the object
'd'. (That 'd' was assigned to in the previous statement has absolutely
no relevance.)


The condition

if ((d = b*b-4*a*c) > 0) ...

uses the result of the assignment operator in an expression, but it
uses it /before/ the next sequence point, so it's okay.

HTH,
-Arthur
 
C

Christian Bau

Barry Schwarz said:
Could someone please explain what section 6.5.16-4 means

"The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined."

I understand the order of evaluation part.

d = b*b-4*a*c;
if (d>0) ...

This is pretty common code and obviously not undefined behavior if the
variables are properly defined and assigned values. But it seems that
the if statement attempts to access the result of the previous
assignment operator after the end of statement sequence point as
described in the quote. What am I misinterpreting?

It is not accessing the "result of the assignment operator", it is
accessing the variable d. You have to do some pretty weird things to
"access the result of an assignment operator":

typedef struct { int x [3]; } mystruct;
mystruct a, b;
int* p;

p = &(a = b).x[2];
*p = 3;

Normally, if you have
int i = 3, j = 4;
i = j;

the result of the assignment operator is not "j", and it is not "i", but
the number 4. In the example above, the "result of the assignment
operator" is a value of type mystruct, but it is not a or b. I managed
to get the address of an element of that struct into p; p is not equal
to &a.x[2] or &b.x[2]. The assignment *p = 3; is undefined behavior.
 
J

junky_fellow

Arthur J. O'Dwyer said:
The result of the assignment operator is discarded. It never gets
used. What gets used in the 'if' statement is the value of the object
'd'. (That 'd' was assigned to in the previous statement has absolutely
no relevance.)

Can you please elaborate why the result of assignment operator is
discarded ? i even test the above condition by writing a program,
but the behaviour was as expected. The value assigned to 'd' was
not discarded. So, when and where such scenarios would cause undefined
behaviour.

thanx in advance for any help/hints....
 
M

Mark Piffer

Christian Bau said:
Barry Schwarz said:
Could someone please explain what section 6.5.16-4 means

"The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined."

You have to do some pretty weird things to
"access the result of an assignment operator":

typedef struct { int x [3]; } mystruct;
mystruct a, b;
int* p;

p = &(a = b).x[2];
*p = 3;

Normally, if you have
int i = 3, j = 4;
i = j;

the result of the assignment operator is not "j", and it is not "i", but
the number 4. In the example above, the "result of the assignment
operator" is a value of type mystruct, but it is not a or b. I managed
to get the address of an element of that struct into p; p is not equal
to &a.x[2] or &b.x[2]. The assignment *p = 3; is undefined behavior.

Ok, how about the following:
int a,b,c;
int f(int);

if( (a=b) == f(c) ) { // undefined behaviour?
}

As the order of execution is unspecified (is it?), the evaluation sequence could be:
[1] a=b
[2] f(c) // sequence point (according to 6.5.2.2/10)
[3] == // using the result of [1] and [2]

Does some other rule catch this construct?

Mark
 
R

Richard Bos

Can you please elaborate why the result of assignment operator is
discarded ?

Because there's nowhere for it to go to. The statement has finished.
i even test the above condition by writing a program,
but the behaviour was as expected. The value assigned to 'd' was
not discarded.

No, but that's not the same value. It _has_ the same value, but it's not
the same value. Perhaps another example is in order. Say,

x = y = 5;

You'll agree that this is one statement, consisting of two assignment
operations, right? Ok, first of all, = binds to the right, so x = y = 5
is x = (y = 5), not (x = y) = 5. With that in mind, what happens is:

- 5 is evaluated. Its value is, no surprise there, 5.
- the right assignment operation assigns the value of its right operand,
5, to its left operand, y, which now also has the value of 5.
- The right assignment operation _also_ passes the value of its right
operand on, up the evaluation tree.
- The left assignment operation assigns the value of its right
operand, which just happens to be the value of the right assignment,
which in turn is the value of _its_ right operand, which was 5 (ok,
enough whiches already!), to its left operand, x. Now x also has
a value of 5.
Note that by this time the value of y does not matter any more. If y
is volatile, and gets changed behind the program's back between the
two assignments, that does not matter a jot. What gets assigned to x
is _not_ the value of y, but the value of the right assignment.
- The right assignment also passes the value of its right operand up the
evaluation tree.
- Since there is no further operator to use this value, however, it is
discarded. The statement is now complete, and there is a sequence
point here.
So, when and where such scenarios would cause undefined behaviour.

In very convoluted situations, since you need to access a temporary
value in a previous statement, which has already finished. I'm not even
sure Christian's example is valid ISO C; even if it is, it's not _good_
ISO C.

Richard
 
J

junky_fellow

Because there's nowhere for it to go to. The statement has finished.


No, but that's not the same value. It _has_ the same value, but it's not
the same value. Perhaps another example is in order. Say,

x = y = 5;

You'll agree that this is one statement, consisting of two assignment
operations, right? Ok, first of all, = binds to the right, so x = y = 5
is x = (y = 5), not (x = y) = 5. With that in mind, what happens is:

- 5 is evaluated. Its value is, no surprise there, 5.
- the right assignment operation assigns the value of its right operand,
5, to its left operand, y, which now also has the value of 5.

If y is a volatile variable, and its value gets changed at this point,
then which value will be assigned to x, new value of y or 5 ?
 
D

Dan Pop

In said:
If y is a volatile variable, and its value gets changed at this point,
then which value will be assigned to x, new value of y or 5 ?

Do yourself a favour and read a tutorial C book.

Dan
 
R

Richard Bos

If y is a volatile variable, and its value gets changed at this point,
then which value will be assigned to x, new value of y or 5 ?

Did you even read anything after this point? For example, this:

Richard
 
L

lawrence.jones

Richard Bos said:
- The right assignment operation _also_ passes the value of its right
operand on, up the evaluation tree.

Not quite, it passes the new value of its left operand up the tree. It
makes a difference if there is an implicit conversion during the
assignment. For example:

float f;
int i;

f = i = 2.5;

The value assigned to f is 2, not 2.5. Note that it's the value after
assignment that's passed on, not necessarily the current value, so if i
were volatile, the compiler would not be obliged to re-read it to
determine the value.

-Larry Jones

It doesn't have a moral, does it? I hate being told how to live my life.
-- Calvin
 
J

junky_fellow

Did you even read anything after this point? For example, this:
I had read the lines many times before asking that question.
i had in my mind that the value assigned to x should be the new value
of y and not the 5, in case it gets changed behind the program's back.
i don't think that the compiler will reread the previous value (i.e. 5 again).
after it gets changed.
 
M

Mark Piffer

Christian Bau said:
Barry Schwarz said:
Could someone please explain what section 6.5.16-4 means

"The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined."

You have to do some pretty weird things to
"access the result of an assignment operator":

typedef struct { int x [3]; } mystruct;
mystruct a, b;
int* p;

p = &(a = b).x[2];
*p = 3;

Normally, if you have
int i = 3, j = 4;
i = j;

the result of the assignment operator is not "j", and it is not "i", but
the number 4. In the example above, the "result of the assignment
operator" is a value of type mystruct, but it is not a or b. I managed
to get the address of an element of that struct into p; p is not equal
to &a.x[2] or &b.x[2]. The assignment *p = 3; is undefined behavior.

Ok, how about the following:
int a,b,c;
int f(int);

if( (a=b) == f(c) ) { // undefined behaviour?
}

As the order of execution is unspecified (is it?), the evaluation sequence could be:
[1] a=b
[2] f(c) // sequence point (according to 6.5.2.2/10)
[3] == // using the result of [1] and [2]

Does some other rule catch this construct?

Mark

Can someone enlighten me about this? Either I got ignored or the
posting vanished too soon from the servers, but I think the question
isn't trivial (ok, for regulars here maybe it is) and certainly not
OT.

regards,
Mark
 
F

Flash Gordon

On 9 Sep 2004 03:57:19 -0700
(e-mail address removed) (Mark Piffer) wrote in message

Ok, how about the following:
int a,b,c;
int f(int);

if( (a=b) == f(c) ) { // undefined behaviour?
}

As the order of execution is unspecified (is it?), the evaluation
sequence could be:[1] a=b
[2] f(c) // sequence point (according to 6.5.2.2/10)
[3] == // using the result of [1] and [2]

Does some other rule catch this construct?

Mark

Can someone enlighten me about this? Either I got ignored or the
posting vanished too soon from the servers, but I think the question
isn't trivial (ok, for regulars here maybe it is) and certainly not
OT.

The order of evaluation of a=b and f(c) does not affect the result in
this case, so why would it be undefined behaviour? Admittedly the value
of a might not be updated until after the comparison has been done, but
the comparison still has to be done against the correct value.

If you had:
if ((c=b)==f(c))
or:
if ((a=c)==f(c))
you would have undefined behaviour.
 
D

Dan Pop

In said:
(e-mail address removed) (Mark Piffer) wrote in message

Ok, how about the following:
int a,b,c;
int f(int);

if( (a=b) == f(c) ) { // undefined behaviour?
}

As the order of execution is unspecified (is it?), the evaluation
sequence could be:[1] a=b
[2] f(c) // sequence point (according to 6.5.2.2/10)
[3] == // using the result of [1] and [2]

Does some other rule catch this construct?

Mark

Can someone enlighten me about this?

Try posting to comp.std.c to improve your chances of getting some
enlightenment. Your analysis looks correct to me: for no good reason,
6.5.16p4 renders the behaviour of your example undefined.
The order of evaluation of a=b and f(c) does not affect the result in
this case, so why would it be undefined behaviour?

Because 6.5.16p4 (quoted in Mark's post) says so.
Admittedly the value
of a might not be updated until after the comparison has been done, but
the comparison still has to be done against the correct value.

The value of a was updated in the problematic scenario. See the
evaluation order posted by Mark.
If you had:
if ((c=b)==f(c))
or:
if ((a=c)==f(c))
you would have undefined behaviour.

I can see no additional problems in your second example. Why would be it
any different from Mark's example?

Dan
 
C

CBFalconer

Flash said:
.... snip ...

If you had:
if ((c=b)==f(c))
Yes

or:
if ((a=c)==f(c))
No.

you would have undefined behaviour.

In the latter case c is being accessed only to extract its value,
not to alter it. Assuming it is not a volatile value.
 

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
474,146
Messages
2,570,832
Members
47,374
Latest member
EmeliaBryc

Latest Threads

Top