Stewart Brodie wrote:
....
Whether you agree or not, I think that the reasoning goes like this: If the
return value from main is considered "output", and since the size of int is
implementation-defined[*], the program cannot be strictly conforming as this
would constitute output which depends on implementation-defined behaviour.
That's not quite it. Whether or not the output is "dependent upon"
implementation-defined behavior should, I think, be evaluated with
respect to the values in the output, not their representation.
The tricky question is the fact that a return value from main() is
equivalent to passing that value to exit(). The value passed to exit()
is NOT said to be passed back to the calling environment (though that is
indeed what happens in many Unix and Unix-like operating systems).
Instead, a return value of 0 or EXIT_SUCCESS from main() causes "an
implementation-defined form of the status _successful termination_" to
be returned by the program itself. A return value of EXIT_FAILURE from
main() causes "an implementation-defined form of the status
_unsuccessful termination_" to be returned by the program itself. All
other cases result in an implementation-defined status being returned by
the program. In a Unix-like environment, the exit status is an integer
value; but that's not required by the C standard. A conforming
implementation of C could turn on a green light for "_successful
termination_" and a red one for "_unsuccessful termination_", and a
yellow one for all other values.
The fact the form of the exit status is implementation-defined is the
core of the issue. It's debatable whether the exit status counts as
output - I believe that it should. I gather from Doug's arguments that
it's the value which is passed to exit() which he considers the true
output; that the exit status is outside the scope of the standard. I
would agree that this is a reasonable approach for defining conformance;
I just don't see anything in the definition of "strictly conforming"
that actuall says that. The value passed to exit() never makes it out of
the program; it can't count as output. The exit status that it causes to
be returned by the program does make it out, so it should count as
output.
However, I'm not pushing this issue as strongly as the corresponding
issue the standard I/O functions. That's because I'm not entirely clear
on one issue: does behavior which produces as output an
implementation-defined translation of the exit status count as output
dependent on implementation-defined behavior? The behavior (at least for
the values 0, EXIT_SUCCESS, and EXIT_FAILURE) could arguably be
described as standard-defined; it's the status, not the behavior, which
is implementation-defined. I'm not sure this is a valid argument, but my
uncertainty about the matter makes me unwilling to push it. If it is not
a valid argument, then the set of strictly conforming programs would
consist only of programs that never exit.