472,988 Members | 3,244 Online

# Bit Pattern Problem

Hi Everyone. Thanks for the help with the qudratic equation problem...I
didn't think about actually doing the math...whoops. Anyway... I'm
having some trouble getting the following program to work. I want to
output a bit pattern from base 10 input. All I get is a zero after the
input...I've looked over the code but can't see the problem...any ideas?
/* display the bit pattern corresponding to
a signed decimal integer */

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int a, b, m, count, nbits;

/* determine the word size in bits and set the initial mask */
nbits = 8 * sizeof(int);
m = 0x1 << (nbits - 1); /* Place 1 in leftmost position */

/* main loop */
do {
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);
scanf("%d", &a);

/* output the bit pattern */
for(count = 1; count <= nbits; count++); {
b = (a & mask) ? 1 : 0; /* set display bit on or off */
printf("%x", b); /* print display bit */
if (count % 4 == 0)
printf(" "); /* blank space after ever 4th digit */
mask >>= 1; /* shift mask 1 position to the right */
}
} while (a != 0);
return EXIT_SUCCESS; /* If it's there why not use it people! */
}

Nov 14 '05 #1
47 5179
fb wrote:
nbits = 8 * sizeof(int);

The error is on this line.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #2

Derrick Coetzee wrote:
fb wrote:
nbits = 8 * sizeof(int);

The error is on this line.

right-o thanks.

Nov 14 '05 #3
Derrick Coetzee wrote:
fb wrote:
nbits = 8 * sizeof(int);

The error is on this line.

Oops, no it's not. I'm an idiot. The actual error is on this line:
for(count = 1; count <= nbits; count++); {

Watch out for those accidental semicolons! ^

--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #4

Derrick Coetzee wrote:
Derrick Coetzee wrote:
fb wrote:
nbits = 8 * sizeof(int);

The error is on this line.

Oops, no it's not. I'm an idiot. The actual error is on this line:
> for(count = 1; count <= nbits; count++); {

Watch out for those accidental semicolons! ^

cool...ok. ty.

Nov 14 '05 #5
On Wed, 01 Sep 2004 22:35:48 -0400, Derrick Coetzee wrote:
fb wrote:
nbits = 8 * sizeof(int);

The error is on this line.

Well, the line shouldn't be written that way, but I doubt that is the
problem. If anything, it should be:

nbits = CHAR_BIT * sizeof (int);

--Mac
Nov 14 '05 #6
On Thu, 02 Sep 2004 01:21:47 +0000, fb wrote:
Hi Everyone. Thanks for the help with the qudratic equation problem...I
didn't think about actually doing the math...whoops. Anyway... I'm
having some trouble getting the following program to work. I want to
output a bit pattern from base 10 input. All I get is a zero after the
input...I've looked over the code but can't see the problem...any ideas?
/* display the bit pattern corresponding to
a signed decimal integer */

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int a, b, m, count, nbits;

/* determine the word size in bits and set the initial mask */
nbits = 8 * sizeof(int);
m = 0x1 << (nbits - 1); /* Place 1 in leftmost position */

/* main loop */
do {
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);
scanf("%d", &a);

/* output the bit pattern */
for(count = 1; count <= nbits; count++); {
Someone else already pointed out that you didn't mean to put a semicolon
after your for loop. That collapses it to an empty loop.
b = (a & mask) ? 1 : 0; /* set display bit on or off */
printf("%x", b); /* print display bit */
if (count % 4 == 0)
printf(" "); /* blank space after ever 4th digit */
mask >>= 1; /* shift mask 1 position to the right */
I don't think the above line will do what you expect.

From the last public draft of c89:

3.3.7 Bitwise shift operators
[...]
The result of E1 >> E2 is E1 right-shifted E2 bit positions.
[...]
If E1 has a signed type and a negative
value, the resulting value is implementation-defined.

At the machine level, you sometimes see a shift with sign extension for
signed integers, and your implementation might use that type of shift
rather than a logic shift. What this means is that shifting a negative
number to the right may fill the higher order bits with 1's. The
documentation for your implementation should say what it does, though.

As far as I know, which may not be very far, every implementation will
probably either fill the high order bits with zeros or fill them with ones.
} } while (a != 0);
return EXIT_SUCCESS; /* If it's there why not use it people! */
}

--Mac

Nov 14 '05 #7
fb wrote:
.... snip ... I'm having some trouble getting the following program to work.
I want to output a bit pattern from base 10 input. All I get is
a zero after the input...I've looked over the code but can't see
the problem...any ideas?

/* display the bit pattern corresponding to
a signed decimal integer */

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int a, b, m, count, nbits;

/* determine the word size in bits and set the initial mask */
nbits = 8 * sizeof(int);
You should #include <limits.h> and replace 8 by CHAR_BIT. Bytes
need not contain 8 bits.
m = 0x1 << (nbits - 1); /* Place 1 in leftmost position */
To do this m should be an unsigned int. Shifting into the sign
position results in undefined behavior. Unsigned ints don't have
a sign bit. Make all the variables unsigned.

/* main loop */
do {
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a); ^^^
What is this? You also need a "fflush(stdin);" after this.
scanf("%d", &a);
Check the result from scanf, which should be 1. Maybe:
if (1 != scanf("%ud", &a)) break;

/* output the bit pattern */
for(count = 1; count <= nbits; count++); { ^
What's this semicolon for?
b = (a & mask) ? 1 : 0; /* set display bit on or off */
printf("%x", b); /* print display bit */
simpler: putc(b + '0', stdout);
if (count % 4 == 0)
printf(" "); /* blank space after ever 4th digit */
simpler: putc(' ', stdout);
mask >>= 1; /* shift mask 1 position to the right */
}
} while (a != 0);
return EXIT_SUCCESS; /* If it's there why not use it people! */
}

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #8
>> /* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);

^^^
What is this? You also need a "fflush(stdin);" after this.

No, you absolutely NEVER need a "fflush(stdin)". If you absolutely
have to invoke undefined behavior, use fflush(void main()). It will
probably save you a lot of time by failing to compile.

Gordon L. Burditt
Nov 14 '05 #9

"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...

/* main loop */
do {
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);

^^^
What is this? You also need a "fflush(stdin);" after this.

Make that:

fflush(stdout);

But you knew that. :-)

-Mike
Nov 14 '05 #10
Mac wrote:
mask >>= 1; /* shift mask 1 position to the right */

I don't think the above line will do what you expect.

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.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #11

"fb" <fb@goaway.net> wrote in message
news:LAuZc.299540\$gE.33632@pd7tw3no...
Hi Everyone. Thanks for the help with the qudratic equation problem...I didn't think about actually doing the math...whoops.
It's actually a very, very big oops that I hope you learn from
and don't just hand wave it.

Computers are really, really stupid. They crunch numbers - and
that's about it. It is up to YOU to solve the problem. Before you
start coding you should try some hand cases and crank the math
and you should especially do that as soon as a problem arises.
There seems to be an ever increasing trend towards just wanting
to throw code at the compiler without understanding what that
code does or is even supposed to do. Don't let yourself fall into
that trap.
Anyway... I'm
having some trouble getting the following program to work. I want to output a bit pattern from base 10 input. All I get is a zero after the input...I've looked over the code but can't see the problem...any ideas?
All you get is "a zero"? As in a single zero? Even though you
have a loop that is guaranteed to print out something every time
through it? What does that tell you? Either the test only passes
the first time through, or the loop code isn't the code you think
it is. If examining the code with this in mind doesn't tell you
something, then instrument the loop by printing out the value of
count within the body of the loop. If it prints out "1" then the
loop is only executing once - look for something in the loop that
is changing one of the values in the test expression. If it
prints out a "9" then what you thought was the loop is not
actually part of the loop. There's a REAL common mistake that can
result in that - so learning how to track it down through
systematic debugging when the Mark II eyeballs insist on skipping
over it (which that are want to do because, as a human with a
functioning human brain, you automatically tend to see what you
WANT the code to be instead of what the code actually IS) can be
a very valuable lesson. I'll leave it for you to track down this
problem further.

You have another potential problem in that any time you do right
shift operations on signed integers, you don't know for sure what
it going to get shifted in to the vacated bit position. You also
don't know for sure how negative values are represented - but
that's sort of the point of the exercise, isn't it?

This is my take on performing any kind of bit banging - the folks
that wrote C intended it to be primarily a high level language
where the programmer worked with "values" and not
"representations". They therefore primarily define how the
different operations behave with respect to the values being
represented and not the representations themselves. They leave it
up to the compiler designer to make that happen and leave them
free to play whatever games they like to (subject to a few
constraints) with the internal representations. But, they
recognize that a few people will have the need/desire to do bit
banging and so they defined a minimal set of operations that have
to have completely well-defined effects on the internal
representation - but imposing this constraint imposes unnecessary
limitations on the games the compiler writer can play in working
with the "values", so the ONLY data type (as far as I know) that
they included in this tightly constrained bit-level definition
are the unsigned integers. Not the integers, only the unsigned
integers. Therefore, only bit bang unsigned integers.

/* display the bit pattern corresponding to
a signed decimal integer */

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int a, b, m, count, nbits;

/* determine the word size in bits and set the initial mask */ nbits = 8 * sizeof(int);
m = 0x1 << (nbits - 1); /* Place 1 in leftmost position */

/* main loop */
do {
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);
scanf("%d", &a);

/* output the bit pattern */
for(count = 1; count <= nbits; count++); {
b = (a & mask) ? 1 : 0; /* set display bit on or off */
printf("%x", b); /* print display bit */
if (count % 4 == 0)
printf(" "); /* blank space after ever 4th digit */
mask >>= 1; /* shift mask 1 position to the right */
}
} while (a != 0);
return EXIT_SUCCESS; /* If it's there why not use it people! */ }

Nov 14 '05 #12

"fb" <fb@goaway.net> wrote in message
news:dRvZc.285714\$M95.236771@pd7tw1no...

Derrick Coetzee wrote:
fb wrote:
nbits = 8 * sizeof(int);

The error is on this line.

right-o thanks.

So....that told you what the problem is?

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.
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
is very high on your priority list.

Nov 14 '05 #13

"Derrick Coetzee" <dc****@moonflare.com> wrote in message
news:ch**********@news-int2.gatech.edu...
Mac wrote:
mask >>= 1; /* shift mask 1 position to the right */
I don't think the above line will do what you expect.

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.
But what is the basis for assuming two's complement semantics?

Even if it is, let's say that I have a four bit two's complement
value represented as 1000 stored in a signed variable m. What
value is that? What value will get stored in the four bit
unsigned variable n if I use n=m ?

As assignments between signed and unsigned data types of the same
basic type required to copy the bit pattern if the value in the
expression can't be represented in the type of the object being
assigned to? Or is this undefined behavior?
As an aside, in my experience, even
signed variable shifts typically get compiled into logical rather than arithmetic shifts.

That's been the exact opposite of mine. For instance, the
following code:

#include <stdio.h>
int main(void)
{
int i;

i = -8;
printf("%i %i\n", i, i >> 1);
return 0;
}

printed:

-8 -4

(Using Borland TurboC/C++ v4.5)

Nov 14 '05 #14
William L. Bahn wrote:
As assignments between signed and unsigned data types of the same
basic type required to copy the bit pattern if the value in the
expression can't be represented in the type of the object being
assigned to? Or is this undefined behavior?

Assigning an out of range value to a signed integer,
is implementation defined.
To assign a negative value to an unsigned,
(UINT_MAX + 1) is added to the value until it becomes non negative.
To assign an out of range positive value to an unsigned,
(UINT_MAX + 1) is subtracted until the value is in range.

--
pete
Nov 14 '05 #15
fb wrote:
I want to output a bit pattern from base 10 input.

/* display the bit pattern corresponding to
a signed decimal integer */

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

#define LENGTH 80
#define str(x) # x
#define xstr(x) str(x)

void bitstr(char *, void const *, size_t);

int main(void)
{
int a, rc;
char abits[CHAR_BIT * sizeof a + 1], string[LENGTH + 1];

fputs("\n\nEnter an integer value (0 to stop): ", stdout);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", string);
if (!feof(stdin)) {
getchar();
}
while (rc == 1) {
a = atoi(string);
bitstr(abits, &a, sizeof a);
printf(" %s = %d\n", abits, a);
if (a == 0) {
break;
}
fputs("\n\nEnter an integer value (0 to stop): ", stdout);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", string);
if (!feof(stdin)) {
getchar();
}
}
return 0;
}

void bitstr(char *str, const void *obj, size_t n)
{
const unsigned char *byte = obj;

while (n--) {
mask = ((unsigned char)-1 >> 1) + 1;
do {
*str++ = (char)(mask & byte[n] ? '1' : '0');
}
*str = '\0';
}

--
pete
Nov 14 '05 #16
"pete" <pf*****@mindspring.com> wrote in message
news:41***********@mindspring.com...
William L. Bahn wrote:
As assignments between signed and unsigned data types of the same
basic type required to copy the bit pattern if the value in the
expression can't be represented in the type of the object being
assigned to? Or is this undefined behavior?
Assigning an out of range value to a signed integer,
is implementation defined.
To assign a negative value to an unsigned,
(UINT_MAX + 1) is added to the value until it becomes non negative.

(or, obviously, ULONG_MAX + 1 etc, according to the type of the object being
assigned to.)

....which, if the negative value can be represented using two's complement in
the number of value bits in the unsigned integer, leaves the unsigned
integer with the two's complement representation of the negative value.

In many cases this means that assignment of a signed integer type to the
corresponding unsigned integer type does indeed simply copy the bit pattern.
To assign an out of range positive value to an unsigned,
(UINT_MAX + 1) is subtracted until the value is in range.

Alex
Nov 14 '05 #17
Gordon Burditt wrote:
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);

^^^
What is this? You also need a "fflush(stdin);" after this.

No, you absolutely NEVER need a "fflush(stdin)". If you absolutely
have to invoke undefined behavior, use fflush(void main()). It will
probably save you a lot of time by failing to compile.

Did I actually write stdin? Must be the cat on the keyboard.
Obviously I meant stdout. Thanks for the correction.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #18
On Thu, 02 Sep 2004 01:21:47 GMT, fb <fb@goaway.net> wrote:
Hi Everyone. Thanks for the help with the qudratic equation problem...I
didn't think about actually doing the math...whoops. Anyway... I'm
having some trouble getting the following program to work. I want to
output a bit pattern from base 10 input. All I get is a zero after the
input...I've looked over the code but can't see the problem...any ideas?
/* display the bit pattern corresponding to
a signed decimal integer */

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int a, b, m, count, nbits;

/* determine the word size in bits and set the initial mask */
nbits = 8 * sizeof(int);
m = 0x1 << (nbits - 1); /* Place 1 in leftmost position */

/* main loop */
do {
/* read a signed integer */
printf("\n\nEnter an integer value (0 to stop): ", a);

a is uninitialized. You cannot pass it to a function in this state,
even if the function will not attempt to evaluate it. This invokes
undefined behavior. In this case, you probably don't want to pass it
at all anyway.

snip
<<Remove the del for email>>
Nov 14 '05 #19
On Thu, 02 Sep 2004 09:41:24 GMT, pete <pf*****@mindspring.com> wrote:
William L. Bahn wrote:
As assignments between signed and unsigned data types of the same
basic type required to copy the bit pattern if the value in the
expression can't be represented in the type of the object being
assigned to? Or is this undefined behavior?
Assigning an out of range value to a signed integer,
is implementation defined.

No, it is undefined.
To assign a negative value to an unsigned,
(UINT_MAX + 1) is added to the value until it becomes non negative.
To assign an out of range positive value to an unsigned,
(UINT_MAX + 1) is subtracted until the value is in range.

<<Remove the del for email>>
Nov 14 '05 #20

William L. Bahn wrote:
"fb" <fb@goaway.net> wrote in message
news:dRvZc.285714\$M95.236771@pd7tw1no...

Derrick Coetzee wrote:

fb wrote:
nbits = 8 * sizeof(int);
The error is on this line.
right-o thanks.

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
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.

Nov 14 '05 #21
On Thu, 02 Sep 2004 01:06:38 -0400, Derrick Coetzee wrote:
Mac wrote:
mask >>= 1; /* shift mask 1 position to the right */

I don't think the above line will do what you expect.

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

Nov 14 '05 #22
In <ch*************************@theriver.com> Barry Schwarz <sc******@deloz.net> writes:
On Thu, 02 Sep 2004 09:41:24 GMT, pete <pf*****@mindspring.com> wrote:
William L. Bahn wrote:
As assignments between signed and unsigned data types of the same
basic type required to copy the bit pattern if the value in the
expression can't be represented in the type of the object being
assigned to? Or is this undefined behavior?

Assigning an out of range value to a signed integer,
is implementation defined.

No, it is undefined.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23
On 6 Sep 2004 16:13:24 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <ch*************************@theriver.com> Barry Schwarz <sc******@deloz.net> writes:
On Thu, 02 Sep 2004 09:41:24 GMT, pete <pf*****@mindspring.com> wrote:
William L. Bahn wrote:

As assignments between signed and unsigned data types of the same
basic type required to copy the bit pattern if the value in the
expression can't be represented in the type of the object being
assigned to? Or is this undefined behavior?

Assigning an out of range value to a signed integer,
is implementation defined.

No, it is undefined.

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>>
Nov 14 '05 #24
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>>
Nov 14 '05 #25

On Mon, 6 Sep 2004, Barry Schwarz wrote:

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
Nov 14 '05 #26
In article <ch*************************@theriver.com>,
Barry Schwarz <sc******@deloz.net> wrote:
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.
Nov 14 '05 #27
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote in message news:<Pi**********************************@unix49. andrew.cmu.edu>...
On Mon, 6 Sep 2004, Barry Schwarz wrote:

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.)

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....

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

Nov 14 '05 #28
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote in message news:<ch*********************************@slb-newsm1.svr.pol.co.uk>...
In article <ch*************************@theriver.com>,
Barry Schwarz <sc******@deloz.net> wrote:
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.

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
Nov 14 '05 #29
ju**********@yahoo.co.in (junky_fellow) wrote:
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote in message news:<Pi**********************************@unix49. andrew.cmu.edu>...
On Mon, 6 Sep 2004, Barry Schwarz wrote:
d = b*b-4*a*c;
if (d>0) ...
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

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
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
Nov 14 '05 #30
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote in message news:<41*****************@news.individual.net>...
ju**********@yahoo.co.in (junky_fellow) wrote:
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote in message news:<Pi**********************************@unix49. andrew.cmu.edu>...
On Mon, 6 Sep 2004, Barry Schwarz wrote:

> d = b*b-4*a*c;
> if (d>0) ... 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

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

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 ?

- 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

Nov 14 '05 #31
In <8c**************************@posting.google.com > ju**********@yahoo.co.in (junky_fellow) writes:
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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #32
ju**********@yahoo.co.in (junky_fellow) wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote in message news:<41*****************@news.individual.net>...
- 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 ?

Did you even read anything after this point? For example, this:
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.

Richard
Nov 14 '05 #33
Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:

- 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
Nov 14 '05 #34
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote in message news:<41*****************@news.individual.net>...
ju**********@yahoo.co.in (junky_fellow) wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote in message news:<41*****************@news.individual.net>...
- 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 ?

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

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.
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.

Richard

Nov 14 '05 #35
so************@yahoo.com (Mark Piffer) wrote in message news:<cc**************************@posting.google. com>...
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote in message news:<ch*********************************@slb-newsm1.svr.pol.co.uk>...
In article <ch*************************@theriver.com>,
Barry Schwarz <sc******@deloz.net> wrote:
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.

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

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
Nov 14 '05 #36
On 9 Sep 2004 03:57:19 -0700
so************@yahoo.com (Mark Piffer) wrote:
so************@yahoo.com (Mark Piffer) wrote in message

<snip>
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

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 ((c=b)==f(c))
or:
if ((a=c)==f(c))
you would have undefined behaviour.
--
Flash Gordon
Sometimes I think shooting would be far too good for some people.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #37
pete wrote:
a = atoi(string);

a = (int)strtol(string, NULL, 10);

would avoid undefined behavior.

--
pete
Nov 14 '05 #38
In <qs************@brenda.flash-gordon.me.uk> Flash Gordon <sp**@flash-gordon.me.uk> writes:
On 9 Sep 2004 03:57:19 -0700
so************@yahoo.com (Mark Piffer) wrote:
so************@yahoo.com (Mark Piffer) wrote in message
<snip>
> 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

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.
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?

Because 6.5.16p4 (quoted in Mark's post) says so.
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 ((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
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #39
Flash Gordon wrote:
.... snip ...
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.

--
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"We have always known that heedless self-interest was bad
morals. We now know that it is bad economics" - FDR
Nov 14 '05 #40
In article <qs************@brenda.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.uk> wrote:
if ((c=b)==f(c))
or:
if ((a=c)==f(c))
you would have undefined behaviour.

The second one has no undefined behavior.
Nov 14 '05 #41
On Thu, 09 Sep 2004 19:40:51 GMT
CBFalconer <cb********@yahoo.com> wrote:
Flash Gordon wrote:

... snip ...

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.

Sorry, I flipped languages for a moment to one that allows pass by
reference.
--
Flash Gordon
Sometimes I think shooting would be far too good for some people.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #42

On Thu, 9 Sep 2004, Flash Gordon wrote:

so************@yahoo.com (Mark Piffer) wrote:
so************@yahoo.com (Mark Piffer) wrote...
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]
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?

Because the Standard says so. Dan Pop's response is correct, as usual;
and most of the other replies are wrong. If you're having trouble
figuring out why the Standard says it's UB, it might help to consider the
perfectly reasonable function definition

int f(int x) { a = x; }

(Then again, it might not. ;-)
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.
Not if it's undefined. :)
if ((c=b)==f(c))
or:
if ((a=c)==f(c))
you would have undefined behaviour.

Those examples aren't any different from the original example; in fact,
they're just special cases of the original (the first where a:=:c and the
second where b:=:c).

HTH,
-Arthur
Nov 14 '05 #43
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
so************@yahoo.com (Mark Piffer) wrote...

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]

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 the Standard says so. Dan Pop's response is correct, as usual;
and most of the other replies are wrong. If you're having trouble
figuring out why the Standard says it's UB, it might help to consider the
perfectly reasonable function definition

int f(int x) { a = x; }

int c;
memset(x, c = 0, sizeof x);
Nov 14 '05 #44

In article <84**************************@posting.google.com >, ol*****@inspire.net.nz (Old Wolf) writes:

int c;
memset(x, c = 0, sizeof x);

That looks OK to me. N869 6.5.16p4 says that accessing the result of
the assignment operator *after the next sequence point* causes UB;

if ((a=b) == f(c))

undefined (because there's a sequence point after the arguments to f
are evaluated). In your example, the result of the assignment
operator (in "c = 0") is accessed before the sequence point that
occurs when all of memset's arguments have been evaluated, because
accessing it is part of evaluating memset's arguments; hence no UB.

So, curiously enough,

if ((a=b) == c)

is legal, but eg

if ((a=b) == (c,d))

is not, because of the sequence point caused by evaluating the first
operand of the comma operator.

OK, now someone should point out where I got it wrong...

(I'm glad Mark re-posted his question. This was a tricky one, and
I certainly hadn't noticed it before.)
--
Michael Wojcik mi************@microfocus.com

The lark is exclusively a Soviet bird. The lark does not like the
other countries, and lets its harmonious song be heard only over the
fields made fertile by the collective labor of the citizens of the
happy land of the Soviets. -- D. Bleiman

Nov 14 '05 #45
In article <ch*********@news3.newsguy.com>,
mw*****@newsguy.com (Michael Wojcik) wrote:
ol*****@inspire.net.nz (Old Wolf) writes:

int c;
memset(x, c = 0, sizeof x);

That looks OK to me. N869 6.5.16p4 says that accessing the result of
the assignment operator *after the next sequence point* causes UB;

if ((a=b) == f(c))

undefined (because there's a sequence point after the arguments to f
are evaluated). In your example, the result of the assignment
operator (in "c = 0") is accessed before the sequence point that
occurs when all of memset's arguments have been evaluated, because
accessing it is part of evaluating memset's arguments; hence no UB.

So, curiously enough,

if ((a=b) == c)

is legal, but eg

if ((a=b) == (c,d))

is not, because of the sequence point caused by evaluating the first
operand of the comma operator.

OK, now someone should point out where I got it wrong...

That has been discussed to some length in comp.std.c.

You are not "accessing" the value of the assignment operator. You can
only "access" lvalues. The result of (a=b) is not an lvalue. You can use
it without accessing it.
Nov 14 '05 #46

In article <ch*********************************@slb-newsm1.svr.pol.co.uk>, Christian Bau <ch***********@cbau.freeserve.co.uk> writes:

You are not "accessing" the value of the assignment operator. You can
only "access" lvalues. The result of (a=b) is not an lvalue. You can use
it without accessing it.

Wouldn't that render N869 6.5.16p4 meaningless? It reads:

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.

If "access" only applies to lvalues, and the result of an assignment
operator is never an lvalue, then this statement describes a case
that can't occur.

--
Michael Wojcik mi************@microfocus.com

Thus, the black lie, issuing from his base throat, becomes a boomerang to
his hand, and he is hoist by his own petard, and finds himself a marked man.
-- attributed to a "small-town newspaper editor in Wisconsin"
Nov 14 '05 #47
In article <ci********@news2.newsguy.com>,
mw*****@newsguy.com (Michael Wojcik) wrote:
In article <ch*********************************@slb-newsm1.svr.pol.co.uk>,
Christian Bau <ch***********@cbau.freeserve.co.uk> writes:

You are not "accessing" the value of the assignment operator. You can
only "access" lvalues. The result of (a=b) is not an lvalue. You can use
it without accessing it.

Wouldn't that render N869 6.5.16p4 meaningless? It reads:

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.

If "access" only applies to lvalues, and the result of an assignment
operator is never an lvalue, then this statement describes a case
that can't occur.