> a thing, but there seems to me to be a loophole there. [snip
> elaboration]
The previous responses here haven't been very illuminating, and I
believe have steered the conclusions in a bad direction. First,
when something is "undefined behavior" (as with the "unspecified"
or "implementation-defined" labels) that is not a description of
behavior but rather a specification of what behaviors are
permissible. Also, something people often forget, what's being
addressed is not the behavior of /programs/ but the behavior of
/implementations/. Of course it is common to talk about how a
certain program construct must behave, but that's only a shorthand
for saying the implementation must produce an executable which
when run will act according to the semantic descriptions given in
the Standard. That may be a subtle difference, but here it is an
important one.
Upon encountering a call to waitpid(), what is an implementation
obliged to do? The answer is mostly found in 5.1.1.1 p1 and
5.1.1.2 p1. Each translation unit must be processed, linked with
library functions and also other TU's, and ultimately an executable
produced. During translation a call to waitpid() must be
processed just like any other function call. Similarly during
link time the linkage must be done just the way it would for
any other link-time connection. What does this mean for how
waitpid() behaves? There are two possibilities.
One is that there is a "magic" object file (magic in the sense
that its origins are unknown, but accepted by the linker even
though the compiler didn't produce it) that defines an external
reference for waitpid(), so the hookup is complete. A call to
waitpid() happens in the same way that other function calls do
(ie, the implementation is obliged to do that), but what
waitpid() does is outside the domain of the implementation.
Whatever happens is not defined behavior, unspecified behavior,
implementation-defined behavior, or undefined behavior, because
these terms make sense only in the context of a C implementation
processing (all or part of) a C program. Here that hasn't
happened. Probably the best term for this situation is
"extra-linguistic behavior" - it is simply outside the realm of
what the C standard considers. The call must be done normally;
after that some other set of rules is in charge.
The other possibility is that waitpid() is supplied by one of
the implementation's library components, ie, a component the
implementation knows about. In this case such a function would
count as an extension in the sense of 4 p6. This in turn says
something about the behavior - in section 4 p8, the Standard
requires implementations to defined (among other things) all
extensions. So what waitpid() does must be defined explicitly
(under this scenario) by the implementation, even though it does
not fall under the heading of 'implementation-defined'.
So perhaps you can rest easier now, knowing that in neither case
is the implementation off the hook for what happens when making
a call to waitpid() - after the call is made, maybe, but not
before. :)