Post by Keith ThompsonThe standard never talks about rejection. It requires that "A
conforming hosted implementation shall accept any strictly
conforming program.". No such requirement applies to any program
which is not strictly conforming. (4p6) [...]
What does "accept" mean? I don't see it defined. ...
I would like to address the meaning of "accept". Please bear with
me as I work through excerpts from two postings, the second one
the grandchild of this first one. (Some text may be pruned or
reordered, but I have made an effort to keep the attributions
intact and correct.)
The term "accept" is commonly used in the field of automata theory.
It means something like "to admit as satisfying the criteria" of the
automata in question. For example, if an automata to determine
primality accepts an input it means the input is a prime number.
This sense of accept is close to what the C standard means.
Post by Keith ThompsonCorrect. In the absence of a standard-defined meaning, we're left
with the ordinary English meaning of the word. Since I can accept
a gift without, in any way, being obligated to do anything with it,
I've argued that a implementation could meet that requirement by
issuing the message "Program accepted", and doing nothing else with
it. The message, not being a mandatory diagnostic, is optional.
It's more likely that the ISO C committee meant "accept" in some
more technical sense (probably similar to the usage explained above)
than in the sense of an ordinary English meaning.
Post by Keith ThompsonThe ordinary English meaning of accept is opposite to the meaning of
reject (which is neither defined nor even used in the standard). As
such, citing the text requiring strictly conforming code to be
accepted, is as close as I can come to supporting Keith's skepticism
about a conforming implementation being allowed to reject this code.
The word "accept" has lots of antonyms: deny, veto, snub, shun,
spurn, demur, reject, refuse, resist, rebuff, oppose, decline,
dismiss, disallow, renounce, repudiate, blackball, and disapprove
are just some of the dozens of easily findable antonyms. Looking
over the list, I think a better opposite word is not "reject" but
"dismiss", which suggests these definitions:
accept: admit as suitable for translation (by this implementation)
(opposite): dismiss as unsuitable for translation (by this implementation)
These definitions provide a good fit to how the word "accept" is
used in the C standard, including other parts of the standard that
talk about translation or execution but don't use the word "accept"
explicitly.
Note in particular that "accept" is a prerequisite for translation,
not the other way around, which is consistent with how the standard
uses these terms.
Post by Keith Thompson[it seems inconsistent for "accept" to mean "successfully
translate and execute"]
I fully agree. Whatever "accept" means, it must be something less
strong than "translate and execute".
I don't agree (though I do agree that the standard is unclear on
what it means).
I don't think that printing "Program accepted" and doing nothing
else would satisfy the standard's requirements. [...]
This statement implicitly offers a false dichotomy. What "accept"
means can be less stringent than "translate and execute" but still
imply more than just printing a "program accepted" message.
Post by Keith ThompsonI suggest that "accept" *does* (or at least should) mean
"successfully translate and execute".
Obviously this statement cannot be right. For one thing, it's not
possible. Perhaps more to the point, it is well established that
the C standard allows an implementation to be conforming even if
it can translate and execute only one program. There were heated
debates on the topic when the original C standard was formed. The
meaning of "accept" needs to be determined by what the standard
actually says about its requirements, not what we might want it to
say.
Post by Keith ThompsonThe standard does not specify "the size or complexity of a program
and its data that will exceed the capacity of any specific
data-processing system or the capacity of a particular processor"
(Scope, section 1 paragraph 2) -- so *some* programs will exceed
an implementation's capacity.
5.2.4.1 says that "The implementation shall be able to translate
and execute at least one program that contains at least one
instance of every one of the following limits". That imposes a
restriction on an implementation's capacity limits. (And it does
it in a way that's straightforwardly specified, but such that the
easiest non-perverse way to conform is to have *reasonable*
capacity limits.)
These paragraphs confuse several distinct notions and entities. The
term "limits" is used (in many places) in relation to implementations.
The term "capacity" appears in the standard exactly twice, once in
relation to a data-processing system, and once in relation to a
processor. The compound term "capacity limits" is never used. The
last item in 1p2
[the standard does not specify] all minimal requirements of a
data-processing system that is capable of supporting a conforming
implementation.
makes it clear that "implementations" and "data-processing systems"
are two different things (and of course processors occupy yet a third
category). This distinction makes sense: if I run gcc on my colo
server (which has 1GB of RAM), or if I run gcc on my compute server
(which has 128GB of RAM), in both cases the implementation is gcc (and
glibc or similar); it is only the underlying data-processing system
that is different.
Post by Keith Thompson[...]
My reading of all that is that a conforming implementation must
translate and execute any *correct* program and any *strictly
conforming* program **that does not exceed its capacity limits**.
Implementations have implementation limits (described in many places
in the standard). Data-processing systems (and also processors) have
capacities, about which the standard has nothing to say, not even
implicitly. The compound phrase "capacity limits" is meaningless.
[and now on to the second message]
Post by Keith ThompsonI suggest that "accept" *does* (or at least should) mean
"successfully translate and execute".
If the "one program" for a given implementation of C is strictly
conforming, that would render 5.2.4.1 redundant.
If the "one program" is not strictly conforming, then 5.2.4.1
serves merely to mandate something for one program which was not
strictly conforming, which was already mandated for all strictly
conforming ones.
My interpretation (perhaps not fully supported by the wording of
the standard) is that the requirement to accept any strictly
conforming program is conditional on that program not exceeding
the implementation's capacity.
A. It isn't. The standard means what it says. It's up to us to
find a definition for "accept" that's consistent with what the C
standard does say, not with what we think it ought to say. The
definitions I gave above for "accept" and "dismiss" (meant as
opposite to accept) are consistent with what the standard actually
says, without any problem from what might occur when an attempt is
made to translate a program.
B. Perhaps a better way to understand what "accept" means is to
look at its opposite. This program
int
main(void){
return (((0)));
}
must be accepted (that is, an implementation must deem it suitable
for translation, and attempt to translate it), because it is
strictly conforming. The attempt to translate is key. On the
flip side, this program
int
main(void){
return
((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((
0
))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))
;
}
does not have to be accepted (it isn't strictly conforming, because
it exceeds a minimum implementation limit). An implementation is
free to dismiss the program as being unsuitable for translation (by
that implementation), by virtue of not meeting all the requirements
for a strictly conforming program.
Similarly, consider this source file
extern char big[2305843009213693952];
An implementation is free to dismiss (and so not accept) this source
file, because it exceeds a minimum implementation limit. In fact,
trying to compile it with clang gives an error (under -pedantic),
complaining that the array is too large. Compiling with gcc works
without complaint. Furthermore, this source file
extern char big[2305843009213693951];
is accepted (and successfully translated) by both gcc and clang.
Clearly clang is exercising its "editorial discretion" not to
accept the larger array declaration, which it is entitled to do
because the size of the object 'big' exceeds a specified minimum
implementation limit (for a hosted implementation, which surely gcc
and clang are both meant to be).
Post by Keith ThompsonYou could construct a strictly conforming program (which does not
exceed any of the minimum translation limits) that's so huge and
complex that an implementation could not reasonably be expected to
translate it. A compiler might run out of memory trying to
compile it, and either crash or die with an error message before
it could even determine that the program is strictly conforming.
I don't think it's reasonable to call that "accepting" the
program.
The implementation is accepting the program by virtue of trying to
translate it. If during the attempted translation some unsuitable
condition is discovered the program can be dismissed with an error
message. If on the other hand some resource is exhausted and the
compiler has to give up, it is still accepting the program, which
is, as far as the compiler can tell up to that point, suitable for
translation by this implementation. Deeming an input suitable for
translation doesn't mean an attempted translation will succeed
(which is unknowable, and certainly cannot be guaranteed); it
means only that as far as the compiler can tell there is nothing
in the program text seen up to that point that would make it
unsatisfactory under that implementation. The C standard draws
a bright line for what the lower bar is for which programs must
be deemed suitable for translation; anything above that lower
bar is left up to implementation, and is purely a quality-of-
implementation matter, not a conformance question.