setjmp return value as the right-hand side of a assignmentexpression?

E

essai

Hi all,
In the book "C A reference manual" (Samuel P. Harbison III & Guy L.
Steele Jr) p.455, it is said:
"Standard C requires that the call to setjmp either be ..., the right-
hand side of a simple assignment expression, or ..."

I looked at the standard and found:

"Environmental limits
4 An invocation of the setjmp macro shall appear only in one of the
following contexts:
— the entire controlling expression of a selection or iteration
statement;
— one operand of a relational or equality operator with the other
operand an integer
constant expression, with the resulting expression being the entire
controlling
expression of a selection or iteration statement;
— the operand of a unary ! operator with the resulting expression
being the entire
controlling expression of a selection or iteration statement; or
— the entire expression of an expression statement (possibly cast to
void).
5 If the invocation appears in anyother context, the behavior is
undeï¬ned."

So, according to the Standard C, a statement like this:

jmp_buf env;
int status = setjmp(env);

leads to undefined behaviour, but according to Harbison and Steele, is
perfectly defined.
Who's right? who's wrong?
Thanks by advance, all.
 
E

Eric Sosman

essai said:
Hi all,
In the book "C A reference manual" (Samuel P. Harbison III & Guy L.
Steele Jr) p.455, it is said:
"Standard C requires that the call to setjmp either be ..., the right-
hand side of a simple assignment expression, or ..."

I looked at the standard and found:

"Environmental limits
4 An invocation of the setjmp macro shall appear only in one of the
following contexts:
— the entire controlling expression of a selection or iteration
statement;
— one operand of a relational or equality operator with the other
operand an integer
constant expression, with the resulting expression being the entire
controlling
expression of a selection or iteration statement;
— the operand of a unary ! operator with the resulting expression
being the entire
controlling expression of a selection or iteration statement; or
— the entire expression of an expression statement (possibly cast to
void).
5 If the invocation appears in anyother context, the behavior is
undeï¬ned."

So, according to the Standard C, a statement like this:

jmp_buf env;
int status = setjmp(env);

leads to undefined behaviour, but according to Harbison and Steele, is
perfectly defined.
Who's right? who's wrong?

The International Standard that defines the C programming
language is wrong, *obviously*. How could it be otherwise?

H&S is not the worst existing book on C, but it is the
worst that I happen to possess. (An earlier edition than yours,
apparently, as mine has only 392 pages including the index.)
The first code example in my copy, the very first example that
introduces a brand-new reader to C for the very first time, is
a four-line source file defining one function:

void hello()
{
printf ("Hello!\n");
}

No, the "Reference Manual" does not even mention that this
function would produce undefined behavior if ever called ...
(A C99 compiler would issue a diagnostic, but my H&S dates
from 1991 and can be forgiven for overlooking developments
that were still eight years in the future. But the function
produces undefined behavior even under the C90 rules that
prevailed when it was written -- So what is one to think of
the level of expertise and/or attention to detail exhibited
by Messrs. H and S? One hopes they've improved matters in
more recent editions, but I'm not highly motivated to spend
money to find out -- and your report of their description of
setjmp() suggests that my parsimony has not disadvantaged me.)
 
E

essai

I have the fifth version (2002) of "C A reference manual" and use
n1256 (C99 TC3 september 2008) as Standard C.
 
E

Eric Sosman

essai said:
I have the fifth version (2002) of "C A reference manual" and use
n1256 (C99 TC3 september 2008) as Standard C.

Okay: In case I wasn't clear earlier (tone of voice doesn't
always survive transcription into plain text, so sarcasm and
irony are sometimes lost):

- The Standard is right (by definition)
- H&S are wrong (they contradict the Standard)

End of story.
 
M

Mark Bluemel

So, according to the Standard C, a statement like this:

jmp_buf env;
int status = setjmp(env);

leads to undefined behaviour, but according to Harbison and Steele, is
perfectly defined.
Who's right? who's wrong?

H & S could be correct about what happens in practice with such real-
world implementations as they have encountered. Their contradiction of
the Standard cannot be taken as generally applicable - the Standard is
the standard, the last word, the ex-cathedra statement...
 
B

BGB / cr88192

Mark Bluemel said:
H & S could be correct about what happens in practice with such real-
world implementations as they have encountered. Their contradiction of
the Standard cannot be taken as generally applicable - the Standard is
the standard, the last word, the ex-cathedra statement...

in many projects, one may often have to step "around" the standards...

granted, it is also good to follow the standards, when applicable.

in general, this leads to an odd pattern:
a good portion of a codebase is relatively portable.

other parts, may be almost completely non-portable.

if done well, the non-portable parts can be rewritten/replaced with
relatively little effort, and would serve mostly to provide capabilities
"not otherwise possible" (and, as a cost, dig fairly deeply into the
underlying implementation...).

typically, these distinctions are made either by partitioning the code into
specific source files (non-portable code being designated as such), or
through the use of '#ifdef' and friends...

even then, one has to be careful that their #ifdef's are also portable
(different compilers may indicate the CPU arch, OS, ... in rather different
ways).


or such...
 
J

jameskuyper

Eric said:
Okay: In case I wasn't clear earlier (tone of voice doesn't
always survive transcription into plain text, so sarcasm and
irony are sometimes lost):

- The Standard is right (by definition)
- H&S are wrong (they contradict the Standard)

I thought it would be a good idea to emphasize that the attitude being
expressed by Eric is not, as some have suggested, a cult-like
blindness to the possibility of defects in the standard. The
standard's description of the C language and the C library could be
incorrectly worded, internally inconsistent, or out of sync with real
world C compilers. The language or the library that the standard
describes might be poorly designed, or even impossible to implement.
The actual standard contains examples of a few of these defects.
However, the one thing the Standard cannot be is incorrect; that's
simply because the standard defines what "correct" means in the
context of C.
 
K

Keith Thompson

Eric Sosman said:
H&S is not the worst existing book on C, but it is the
worst that I happen to possess. (An earlier edition than yours,
apparently, as mine has only 392 pages including the index.)
The first code example in my copy, the very first example that
introduces a brand-new reader to C for the very first time, is
a four-line source file defining one function:

void hello()
{
printf ("Hello!\n");
}

In the 5th edition, that example is:

#include <stdio.h> /* defines printf */
void hello(void)
{
printf("Hello!\n");
}

The comment should say "declares" rather than "defines", but the code
is solid.
No, the "Reference Manual" does not even mention that this
function would produce undefined behavior if ever called ...
(A C99 compiler would issue a diagnostic, but my H&S dates
from 1991 and can be forgiven for overlooking developments
that were still eight years in the future. But the function
produces undefined behavior even under the C90 rules that
prevailed when it was written -- So what is one to think of
the level of expertise and/or attention to detail exhibited
by Messrs. H and S? One hopes they've improved matters in
more recent editions, but I'm not highly motivated to spend
money to find out -- and your report of their description of
setjmp() suggests that my parsimony has not disadvantaged me.)

I think the 5th edition's description of setjmp now also agrees with
the standard.
 
K

Keith Thompson

Eric Sosman said:
Keith said:
[... Harbison and Steele, "C: A Reference Manual" ...]
I think the 5th edition's description of setjmp now also agrees with
the standard.

Not according to the quote essai provided, which he says is
from the fifth edition.

You're right, H&S5 gets this wrong. (essai didn't actually say
the quotation is from the 5th edition, but it is; the page numbers
match.) And that error doesn't appear in the errata either; see
<http://www.careferencemanual.com/>.
 
K

Keith Thompson

Keith Thompson said:
Eric Sosman said:
Keith said:
[... Harbison and Steele, "C: A Reference Manual" ...]
I think the 5th edition's description of setjmp now also agrees with
the standard.

Not according to the quote essai provided, which he says is
from the fifth edition.

You're right, H&S5 gets this wrong. (essai didn't actually say
the quotation is from the 5th edition, but it is; the page numbers
match.) And that error doesn't appear in the errata either; see
<http://www.careferencemanual.com/>.

Whoops, essai did mention the 5th edition in a followup.

I've e-mailed a correction to the authors, cc'ed to essai.
 
N

Nick Keighley

which would be wrong
in many projects, one may often have to step "around" the standards...

but not in the case of setjmp()! As others have pointed out there
are good reasons for the apparently arbitary restrictions on setjmp()
calls. The whole setjmp/logjmp system is fragile and shouldn't
be stresssed in any way. See Plauger "The Standard C Library" for
discussion (coincidently I was just re-reading it and I've just
read the setjmp/longjmp bit. Scarey).

granted, it is also good to follow the standards, when applicable.

in general, this leads to an odd pattern:
a good portion of a codebase is relatively portable.

other parts, may be almost completely non-portable.

doesn't seem at all odd to me! How else would you write code! :)
Seriously, this is what your code *should* look like.

if done well, the non-portable parts can be rewritten/replaced with
relatively little effort, and would serve mostly to provide capabilities
"not otherwise possible" (and, as a cost, dig fairly deeply into the
underlying implementation...).

typically, these distinctions are made either by partitioning the code into
specific source files (non-portable code being designated as such), or
through the use of '#ifdef' and friends...

avoid the ifdef way if you possibly can. It leads to messy and obscure
code. Far better is to use architecture specific files.
 
S

Stephen Sprunk

Nick said:
avoid the ifdef way if you possibly can. It leads to messy and obscure
code. Far better is to use architecture specific files.

It depends on how different the target systems are; if I were writing a
thread API wrapper, for example, I'd probably put Windows and POSIX in
separate implementation files -- but if Linux, Solaris, and OSX each
required a few lines of tweaks to the POSIX wrapper, the mental cost of
the #ifdefs is lower than the mental cost of maintaining three different
wrappers that were virtually identical.

S
 
J

jqbalter

Hi all,
In the book "C A reference manual" (Samuel P. Harbison III & Guy L.
Steele Jr) p.455, it is said:
"Standard C requires that the call to setjmp either be ..., the right-
hand side of a simple assignment expression, or ..."

I looked at the standard and found:

"Environmental limits
4 An invocation of the setjmp macro shall appear only in one of the
following contexts:
— the entire controlling expression of a selection or iteration
statement;
— one operand of a relational or equality operator with the other
operand an integer
constant expression, with the resulting expression being the entire
controlling
expression of a selection or iteration statement;
— the operand of a unary ! operator with the resulting expression
being the entire
controlling expression of a selection or iteration statement; or
— the entire expression of an expression statement (possibly castto
void).
5 If the invocation appears in anyother context, the behavior is
undeï¬ned."

So, according to the Standard C, a statement like this:

jmp_buf env;
int status = setjmp(env);

leads to undefined behaviour, but according to Harbison and Steele, is
perfectly defined.
Who's right? who's wrong?
Thanks by advance, all.

Is this a joke? How could the Standard for what is and is not defined behavior be wrong? That's not coherent.
 
K

Keith Thompson

Hi all,
In the book "C A reference manual" (Samuel P. Harbison III & Guy L.
Steele Jr) p.455, it is said:
"Standard C requires that the call to setjmp either be ..., the right-
hand side of a simple assignment expression, or ..." [snip]
Who's right? who's wrong?
Thanks by advance, all.

Is this a joke? How could the Standard for what is and is not defined
behavior be wrong? That's not coherent.

This was discussed here at some length when essai's article was
posted 5 years ago. If you were able to find that old post, you
should be able to find the rest of the discussion. Conclusion:
This is an error in Harbison & Steele; I e-mailed a correction to
the authors at the time.

Incidentally, that error still doesn't appear in the errata at
<http://careferencemanual.com/>.
 
J

jqbalter

Hi all,
In the book "C A reference manual" (Samuel P. Harbison III & Guy L.
Steele Jr) p.455, it is said:
"Standard C requires that the call to setjmp either be ..., the right-
hand side of a simple assignment expression, or ..."
[snip]
Who's right? who's wrong?
Thanks by advance, all.
Is this a joke? How could the Standard for what is and is not defined
behavior be wrong? That's not coherent.



This was discussed here at some length when essai's article was

posted 5 years ago. If you were able to find that old post, you

should be able to find the rest of the discussion. Conclusion:

This is an error in Harbison & Steele; I e-mailed a correction to

the authors at the time.



Incidentally, that error still doesn't appear in the errata at

<http://careferencemanual.com/>.



--

Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>

Working, but not speaking, for JetHead Development, Inc.

"We must do something. This is something. Therefore, we must do this."

-- Antony Jay and Jonathan Lynn, "Yes Minister"

I'm not unaware of any of that but it has no bearing on my comment, which will still be valid when the discussion is a billion years old. The fact is that this thread is still being *referenced*, which is how I ended up here.
 
J

jqbalter

(e-mail address removed) writes:
In the book "C A reference manual" (Samuel P. Harbison III & Guy L..
Steele Jr) p.455, it is said:
"Standard C requires that the call to setjmp either be ..., the right-
hand side of a simple assignment expression, or ..."
Who's right? who's wrong?
Thanks by advance, all.
Is this a joke? How could the Standard for what is and is not defined
behavior be wrong? That's not coherent.
This was discussed here at some length when essai's article was
posted 5 years ago. If you were able to find that old post, you
should be able to find the rest of the discussion. Conclusion:
This is an error in Harbison & Steele; I e-mailed a correction to
the authors at the time.
Incidentally, that error still doesn't appear in the errata at

--
Keith Thompson (The_Other_Keith) (e-mail address removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"



I'm not unaware of any of that but it has no bearing on my comment, whichwill still be valid when the discussion is a billion years old. The fact is that this thread is still being *referenced*, which is how I ended up here.

BTW, the problem that I addressed in Essai's comment is that Essai, among many other people, don't understand what "undefined behavior" is. Essai's question was whether the given code "leads to undefined behaviour", as if "undefined behavior" were some *concrete* behavior displayed by various implementations, rather than a characterization of such code by the defining document of not having defined behavior. Every implementation in the universe could do exactly what we would like it to do and it would still be undefinedbehavior. (And yes, I know that language lawyers such as Keith Thompson already know this.)
 
J

James Kuyper

....
I'm not unaware of any of that but it has no bearing on my comment,
which will still be valid when the discussion is a billion years old.
The fact is that this thread is still being *referenced*, which is
how I ended up here.

Where was it referenced? It might be more appropriate to comment on the
reference, in the same context as the one where the reference occurred.

If the entire thread was referenced, what goal are you trying to achieve
by commenting on it now? Anybody who looks at the entire thread will see
that the point you're making was already made by other people, long
before you made it.
 
K

Kaz Kylheku

Is this a joke? How could the Standard for what is and is not defined behavior be wrong? That's not coherent.

There are two problems with

x = setjmp(...);

One is surmountable; the other isn't.

The first problem is that if x is a variable with automatic storage which is
not volatile-qualified, then the above constitutes an instance of modifying a
non-volatile auto variable after doing a setjmp, before the longjmp takes
place. The value of such a variable is indeterminate. (See paragraph in
description of longjmp.)

The second problem is that when control returns into the setjmp() expression
for a second time via the longjmp invocation, the setjmp-time environment
(all accessible objects) is being restored.

So, imagine that setjmp is being re-activated by a longjmp and is restoring the
value of x:

x = setjmp(...);

But remember that setjmp is not a function, but a macro. It doesn't have a
sequence point between its restoring actions, and the action of returning a
value. So the above constitutes two modifications of object x without an
intervening sequence point.
 

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,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top