How often do you read the C standard?

R

Richard Bos

Ben Pfaff said:
I use it as my primary reference for the standard C library, so a
couple of times a day.

Ditto, on those days on which I write C (which isn't every day).

Richard
 
H

Harald van Dijk

Are you sure? I would expect the expansion to be:

a = a - (b - 1);
ie:
a = a - b + 1;

It's already pointed out that Richard Harter didn't expect otherwise, but
I'd like to point out that a - (b - 1) and a - b + 1 are not equivalent
either. If a and b are integer types, a - b + 1 may cause an overflow
where a - (b - 1) doesn't. If a is a pointer type, and a - (b - 1) points
to the start of an object, a - b + 1 is as invalid as a - b. If a and b
are floating point types, a - (b - 1) and a - b + 1 may even give
different results when both expressions are perfectly valid, for example
when a and b are both 1E99 and 1E99 - 1 == 1E99 because the exact result
is not representable.
 
W

Walter Banks

Keith said:
David Resnick said:
I was yesterday reviewing some code that did make me seek the
standard, simplified as:

a -= b - 1;

I looked at that, and realized that I didn't know offhand whether if a
was 10 and b was 5 the result would be 6 or 4. Section 16.5.16.2
resolved that issue nicely...
[...]

6.5.16.2 would have resolved it even more nicely. :cool:}

There is another frequent misconception illustrated by the following code
fragment.

E1 -= E2; is E1 = E1 - (E2);
but the side effects of E1 are only evaluated once so

*(pointer++) -= 1 is the same as *pointer = *(pointer++) - 1

Regards,
 
I

Ike Naar

I'd like to point out that a - (b - 1) and a - b + 1 are not equivalent
either. If a and b are integer types, a - b + 1 may cause an overflow
where a - (b - 1) doesn't.

What will happen if b is the minimum value for its type?
 
H

Harald van Dijk

What will happen if b is the minimum value for its type?

Assuming b is a signed integer type not narrower than int, the behaviour
of a - (b - 1) is undefined, and depending on the type and value of a,
the behaviour of a - b + 1 may or may not be, so that is another similar
way in which they are not equivalent.
 
H

Harald van Dijk

There is another frequent misconception illustrated by the following
code fragment.

E1 -= E2; is E1 = E1 - (E2);
but the side effects of E1 are only evaluated once so

*(pointer++) -= 1 is the same as *pointer = *(pointer++) - 1

There's no guarantee in

*pointer = *(pointer++) - 1

that the first reference pointer is evaluated before the increment
starts. A common misconception is even that the RHS of an assignment must
be fully evaluated before the LHS is. This is not required, but certainly
allowed, and if this is done, the two expressions behave significantly
differently.
 
I

Ike Naar

Assuming b is a signed integer type not narrower than int, the behaviour
of a - (b - 1) is undefined, and depending on the type and value of a,
the behaviour of a - b + 1 may or may not be, so that is another similar
way in which they are not equivalent.

Thank you; I was puzzled by a remark in your previous post that

which I first interpreted as:
- there exist a, b, such that a - b + 1 will overflow,
- for all a, b : a - (b - 1) will not overflow
(the last assertion is wrong, e.g. for b == XXX_MIN)

but now it looks like your intention was:
- there exist a, b, such that a - b + 1 will overflow but a - (b - 1) will not.
which is correct.

Sorry for the confusion.
 
C

CBFalconer

Walter said:
.... snip ...

There is another frequent misconception illustrated by the
following code fragment.

E1 -= E2; is E1 = E1 - (E2);
but the side effects of E1 are only evaluated once so

*(pointer++) -= 1 is the same as
*pointer = *(pointer++) - 1

However that second line exhibits undefined behavior. I believe
the first line is legitimate. The point here is not single
occurence of side effects, but sequence. I would avoid either.
 
W

Walter Banks

Harald said:
There's no guarantee in

*pointer = *(pointer++) - 1

that the first reference pointer is evaluated before the increment
starts. A common misconception is even that the RHS of an assignment must
be fully evaluated before the LHS is. This is not required, but certainly
allowed, and if this is done, the two expressions behave significantly
differently.

Might be an interesting survey here. Which compilers

behave as
*pointer = *(pointer++) - 1
or
*(pointer++) = *pointer - 1

From my reading of the standard I believe the first is correct

Regards,
 
H

Harald van Dijk

Might be an interesting survey here. Which compilers

behave as
*pointer = *(pointer++) - 1
or
*(pointer++) = *pointer - 1

From my reading of the standard I believe the first is correct

My point was that

*(pointer++) -= 1

has a defined meaning, whereas

*pointer = *(pointer++) - 1

and

*(pointer++) = *pointer - 1

are undefined because they both read and modify pointer without an
intervening sequence point. So either can be equivalent to the original,
depending on the compiler, the options, and the phase of the moon. Your
understanding of what *(pointer++) -= 1 means is correct, as far as I can
tell, and it's just that your replacement version doesn't mean what you
seem to think it does.
 
H

Harald van Dijk

Might be an interesting survey here. Which compilers

behave as
*pointer = *(pointer++) - 1
or
*(pointer++) = *pointer - 1

From my reading of the standard I believe the first is correct

My point was that

*(pointer++) -= 1

has a defined meaning, whereas

*pointer = *(pointer++) - 1

and

*(pointer++) = *pointer - 1

are undefined because they both read and modify pointer without an
intervening sequence point. So either can be equivalent to the original,
depending on the compiler, the options, and the phase of the moon. Your
understanding of what *(pointer++) -= 1 means is correct, as far as I can
tell, and it's just that your replacement version doesn't mean what you
seem to think it does.
 
W

Walter Banks

Harald said:
My point was that

*(pointer++) -= 1

has a defined meaning,

Okay we are on the same page. The standard is clear that the -= expansion doesn't
suddenly create a sequence point issue or problem.

w..
 
T

Tim Rentsch

Eric Sosman said:
Usually, I refer to the Standard for one of three reasons (or
sometimes a combination): To shine some light into the language's
dark corners[1], to settle a fine distinction[2], or to look up
the arguments of a function I rarely use[3]. [snip]

[3] E.g., bsearch(). I confess to a degree of dyxlesia about
^^^^^^^^
functions like calloc() and fread() and fwrite(): I can't
seem to remember which size_t argument is the count and which
is the size, so I have to look 'em up. (Strangely, qsort()
doesn't baffle me this way.)

Sorry, I couldn't help laughing when I read this.

One of the best developers I ever met was (and presumably still
is) dyslexic. I never understood (until later) why his homeworks
were written on the back side of the paper; couldn't spell in
many cases to save his life either. But he sure could write code.
 
T

Tim Rentsch

Richard Heathfield said:
David Resnick said:


Whenever I need to, which isn't very often but does happen from time
to time.

Do you know what I use it for *most*? For looking up whether fread
and fwrite take size, count or count, size.

Do you know what I use K&R2 for most? For looking up whether fread
and fwrite take size, count or count, size.

(Whether I use K&R2 or the Standard basically depends on whichever
of them seems less like hard work at the time.)

Why I can't remember that simple detail about fread and fwrite, I
can't tell. But I must have used them hundreds if not thousands of
times over the years, and I still can't keep them straight for more
than about ten minutes at a time.

Thinking of the arguments as count and size:

calloc() takes these arguments in alphabetical order
fread(), fwrite() take these arguments in reverse alphabetical order

Another way to think of (count,size) is as dimensions of
a two-dimensional array of type char

char space[nmemb][size]; // nmemb blocks, each with size char's

Again calloc() takes its arguments in the same two-D order,
and fread(), fwrite() take these arguments in reverse two-D order.

Oh, one more thing: Mt Fuji is 12,365 feet high -- 12 months in
a year, 365 days in a year. Another useless (and wrong, so I've
been told) fact, burned into my brain through a memorable mnemonic.
 
T

Tim Rentsch

Flash Gordon said:
[...snip...] a -= b-1; [...snip...]

A few weeks ago I had an email from a colleague who has been programming
in C certainly since before you could rely on compilers implementing
C89. He, like David, had previously only used a primary expression as
the RHS but this time he did not. He thought that the above was just
shorthand for
a = a - b - 1;
This interpretation leads, of course, to the assumption that "a" will be
assigned the value of 4. Personally I had always understood it correctly
to be
a = a - (b - 1);
I can't remember if when I initially also understood that the LHS is
only evaluated once, but it does seem logical to me now.

My memory is that both these points were covered in K&R1,
because later I never felt any need to look them up,
except to be sure my memory was right.
 
U

user923005

Eric Sosman said:
     Usually, I refer to the Standard for one of three reasons (or
sometimes a combination): To shine some light into the language's
dark corners[1], to settle a fine distinction[2], or to look up
the arguments of a function I rarely use[3].  [snip]
     [3] E.g., bsearch().  I confess to a degree of dyxlesia about

                                                      ^^^^^^^^
         functions like calloc() and fread() and fwrite(): I can't
         seem to remember which size_t argument is the count and which
         is the size, so I have to look 'em up.  (Strangely, qsort()
         doesn't baffle me this way.)

Sorry, I couldn't help laughing when I read this.

One of the best developers I ever met was (and presumably still
is) dyslexic.  I never understood (until later) why his homeworks
were written on the back side of the paper;  couldn't spell in
many cases to save his life either.  But he sure could write code.

I'm dyslexic. I guess with his spelling problems, he had the correct
letters but put them in the wrong place sometimes. I especially do
this a lot when I look up from the paper as I am writing by hand.
E.g.:
bule for 'blue' or hte for 'the', etc.

Normally, I only get the wrong letters {outside of permutations} when
I hit the wrong keys when typing, and almost never when printing by
hand.

As far as the back side of the paper goes...
I approach glass doors slowly and think before I yank because I can
read the writing on the other side that says 'PULL' quite naturally
and so I may yank when I ought to push. I can read a newspaper in a
mirror about as easily as I can read it normally. There is a strange
effect where things that rotate or translate seem very much the same.
For instance, these are all the same letter (everyone else has it
wrong):
b,d,p,q
 
T

Tim Rentsch

Walter Banks said:
Keith said:
David Resnick said:
I was yesterday reviewing some code that did make me seek the
standard, simplified as:

a -= b - 1;

I looked at that, and realized that I didn't know offhand whether if a
was 10 and b was 5 the result would be 6 or 4. Section 16.5.16.2
resolved that issue nicely...
[...]

6.5.16.2 would have resolved it even more nicely. :cool:}

There is another frequent misconception illustrated by the following code
fragment.

E1 -= E2; is E1 = E1 - (E2);
but the side effects of E1 are only evaluated once so

*(pointer++) -= 1 is the same as *pointer = *(pointer++) - 1

The statement

E1 -= E2;

is the same as

(E1_p = &E1, 0) & (E2_v = E2, 0), *E1_p = *E1_p - E2_v;

for suitably typed E1_p and E2_v.
 
T

Tim Rentsch

Walter Banks said:
Might be an interesting survey here. Which compilers

behave as
*pointer = *(pointer++) - 1
or
*(pointer++) = *pointer - 1

From my reading of the standard I believe the first is correct

Disregarding the problem with undefined behavior in both "expansions",
it would be very surprising if any C compiler that's been used by
any significant group of people gets this wrong.
 
C

CBFalconer

user923005 said:
.... snip ...

As far as the back side of the paper goes...
I approach glass doors slowly and think before I yank because I
can read the writing on the other side that says 'PULL' quite
naturally and so I may yank when I ought to push. I can read a
newspaper in a mirror about as easily as I can read it normally.
There is a strange effect where things that rotate or translate
seem very much the same. For instance, these are all the same
letter (everyone else has it wrong):
b,d,p,q

Interesting. I conclude that most dyslexics are not obvious, but
may be detected by apparent slowness in making some elementary
decisions. Maybe that 'most' should be 'many'.
 

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
474,434
Messages
2,571,685
Members
48,796
Latest member
Greg L.

Latest Threads

Top