C Test Incorrectly Uses printf() - Please Confirm

I

Ike Naar

Right. But why not "unspecified" rather than "undefined behaviour"?
Isn't it easy to get unspecified program results which are not
undefined, but still useful based on knowledge of the implementation, or
still portable in that a program does not crash and is guaranteed to
translate?

aw0 and ar1 might interfere with each other in such a way that there
are no results at all (for instance, the hardware might trap when it
detects that the same location is simultaneously read from and written
to).
[snip]

Ok. Isn't it interesting how "any order" for the function calls in
example 6.5.2.2p12 means "one at a time" but we are allowed simultaneous
order for the write of '++a' and the read of 'a + 5'? Or does it?
Isn't it interesting that 6.5.2.2p10 details the unspecified order for
"the function designator, the actual arguments, and subexpressions
within the actual arguments." Why the distinction on "subexpressions"
here? Why not the distinction in 6.5p2?

Here you bring up an interesting point.
The standard says that there is a sequence point between
- the evaluation of function designator and arguments, and
= the actual execution of the function
Now in the following expression:

g(x) + h(y);

are g and h allowed to run simultaneously?
Could there be the following sequence of events:

evaluation of g, x, h, y run g and h evaluation of ``+''
---------------------------+---------------+---------------------
SP0 SP1

After all, there is a sequence point (SP0) between
- evaluation of g and x, and
= the execution of g
Likewise, there is a sequence point (again, SP0) between
- evaluation of h and y, and
= the execution of h

Is there anything in the standard that forbids this?
 
B

Ben Bacarisse

The standard says that there is a sequence point between
- the evaluation of function designator and arguments, and
= the actual execution of the function
Now in the following expression:

g(x) + h(y);

are g and h allowed to run simultaneously?

No, not in any meaningful sense. Execution proceeds as defined by the C
abstract machine and that defines only one locus of execution that moves
through the code (my words but one can find supporting text). Of
course, if you could not tell that the execution is concurrent then it
is permitted, but that's not an interesting observation because... you
can't tell.

The bottom line is that it must appear as if all of g is executed
followed by all of h or all of h followed by all of g.

<snip>
 
I

Ike Naar

No, not in any meaningful sense. Execution proceeds as defined by the C
abstract machine and that defines only one locus of execution that moves
through the code (my words but one can find supporting text).

That's what I thought, too, but I can't seem to find the supporting text.
One thing that comes close is in the "Storage durations of objects"
chapter: "Calling a function that returns suspends but does not end
execution of the block containing the call.". Is that it?
 
S

Shao Miller

Ike said:
That's what I thought, too, but I can't seem to find the supporting text.
One thing that comes close is in the "Storage durations of objects"
chapter: "Calling a function that returns suspends but does not end
execution of the block containing the call.". Is that it?
C1X has "unsequenced" (could even be simultaneous) versus
"indeterminately sequenced", if that helps.

Experience suggests that two reads of a 'volatile' object do not happen
at the same time, but one after the other. C99 allows the
implementation to choose if:

volatile int x = 1;
x = x + x;

is one read or two.

Similarly, that bit from C99 about an outer function's execution being
suspended while in an inner function is congruent with C1X's definition
for called functions being indeterminately sequenced with regards to any
peer evaluations; those peers are evaluated before or after, but not during.

Even if that bit from C99 about an outer function's execution being
suspended while in an inner function is true, perhaps there is something
more which specifies that your 'g' and 'h' cannot be called at exactly
the same time... If they were, that would still mean the outer
function's execution is suspended. If you find the relevant text in the
Standard, it will help to suggest (along with "real-world" 'volatile',
perhaps) that:

Evaluations of expressions have a [specified or unspecified] linear order.

(The above is not a quote.)

Isn't it nice that '++a' is such a trivial thing that it could be
evaluated concurrently with a read of 'b', but a 'g' function call
doesn't seem to enjoy the same treatment, no matter how trivial the body
of 'g' might be? 'volatile' (in the "real" world, perhaps) and function
calls thus allow the programmer a bit of control by making things
somewhat atomic.
 
B

Ben Bacarisse

That's what I thought, too, but I can't seem to find the supporting text.
One thing that comes close is in the "Storage durations of objects"
chapter: "Calling a function that returns suspends but does not end
execution of the block containing the call.". Is that it?

In part. It is more the sum total of the text. Nowhere is there any
support for the idea that the locus of execution can "split". If that
were the case, it would surely be documented in 5.1.2.3 "Program
execution".

In addition, when a text like the C standard says "the order of
evaluation is unspecified" it is a stretch of the language to consider
concurrent evaluations. In plain English, there are two ordering for
the evaluation of the operands of E1+E2: E1 then E2 or E2 then E1.
 
B

Ben Bacarisse

pete said:
When the evaluations of expressions
(such as p and q in (*p++ = *q++))
include side effects without intervening sequence points,
then the evaluations of those expressions
(such as p and q)
can be said to occur concurrently.

Yes, I agree, but the wider context was whether concurrency was
permissible in an observable sense.

<snip>
 
L

lawrence.jones

Ike Naar said:
That's what I thought, too, but I can't seem to find the supporting text.

6.8p2: Except as indicated, statements are executed in sequence.

Interleaving statements from g and h is not executing them in sequence.
 
S

Shao Miller

6.8p2: Except as indicated, statements are executed in sequence.

Interleaving statements from g and h is not executing them in sequence.
Well, the statements from 'g' execute in sequence relative to statement
execution in 'g' and the statements in 'h' execute in sequence relative
to statement execution in 'h'. What does "in sequence" mean? English
reading order?

But we do have compound statements[1] for those function calls. If
English reading order is to be assumed for "sequence", then the call to
the left-most function should occur before the call to functions to the
right of it, etc. But we have our indication[2] that "any order" is
allowed for the calls, so why not "at the same time" order for those
compound statements, as is so generously offered to other bits of
evaluation?

Anyway, C1X seems like it will be more explicit, as you've pointed out,
Mr. L. Jones.

Reference from "C99" C Standard draft with filename 'n1256.pdf':
[1] 6.9.1p11 "After all parameters have been assigned, the compound
statement that constitutes the body of the function definition is executed."
[2] 6.5.2.2p12 "...the functions f1, f2, f3, and f4 may be called in any
order..."
 

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
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top