-3

Follow-up question for: Do unsupported standard features affect conformance?.

Question: if an implementation supports extra features which are not described in the C standard, nor in any "extension document", then is such implementation conforming?

A simple example: #pragma STDC FP_CONTRACT requires on-off-switch, which is one of ON OFF DEFAULT. However, one implementation in addition to ON OFF DEFAULT does support RESTORE. Hence, such implementation allows writing nonstandard code. Does it mean that such implementation is nonconforming?

Extra question: the C standard tells "what implementation shall/should do". However, does the C standard (or any standard in general) tell "what implementation shall/should not do"? For example, if an implementation does support my_printf (in addition to printf), then is such implementation conforming?

pmor
  • 5,392
  • 4
  • 17
  • 36
  • https://port70.net/~nsz/c/c11/n1570.html#4 What research did you do? – KamilCuk Jul 19 '21 at 10:39
  • 5
    Extra features only cause the implementation to be non-conforming if they affect the behavior of strictly conforming programs. From C17 4/6: "A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program." – Ian Abbott Jul 19 '21 at 10:42
  • 2
    "conforming implementation" means that it shall correctly translate conforming programs, and diagnose conditions which require diagnosis. It does not restrict the implementation from anything else . (Including from proceeding after a diagnostic). – M.M Jul 19 '21 at 10:46
  • Please create an answer. – Yunnosch Jul 19 '21 at 11:02
  • @M.M If a conforming implementation successfully translates strictly conforming programs AND programs which use nonstandard / "nonextention" features (ex.: `#pragma STDC FP_CONTRACT RESTORE`), then is such implementation still conforming? – pmor Jul 20 '21 at 13:12
  • @M.M Answering to myself: the _programs which use nonstandard / "nonextention" features_ are not strictly conforming programs. However, _4. Conformance_ does not say that "a conforming (hosted) implementation shall reject any non-strictly conforming program", because non-strictly conforming program is may be the one that _uses only those features of the language and library_, but _produces output dependent on UB_. I conclude that it is not defined of what a conforming (hosted) implementation shall do with non-strictly conforming program. Is it correct? – pmor Jul 20 '21 at 14:01

1 Answers1

1

The Standard defines three concepts of conformance. In order of meaningfulness, they are a "Strictly Conforming C Program", a "Conforming C Implementation", and a "Conforming C Program".

A Strictly Conforming C Implementation is one whose behavior is fully specified by the Standard. This excludes all non-trivial programs for freestanding implementations, since the Standard doesn't define any form of I/O for them. It also excludes many programs that would be portable if the Standard sought to avoid characterizing as UB any actions whose behavior might conceivably be difficult to define on some implementations, or whose behavior might expose the effects of useful optimization.

A Conforming C Implementation is one which in theory could in theory meaningfully process all Strictly Conforming Programs, but may behave arbitrarily when given any program--strictly conforming or not--that would exceed an implementation's translation limits. That latter caveat creates a loophole big enough to drive a truck through.

While the Standard requires that an implementation be able to accommodate e.g. 127 nested blocks, 511 block-scope identifiers within a block, 1023 members in a struct or union, and 63 characters in an internal identifier's name, it doesn't require that an implementation be able to accommodate 127 nested blocks, each with 511 identifiers that each identify a structure with 1023 members, each with a name that's 63 characters long. Such a requirement would make the language impossible to support on any translation environment with less than four gigs of storage. To avoid making the language impossible to implement, the Standard refrains from requiring that implementations support arbitrary combinations of translation limits. Instead, all that is necessary for conformance is that there exist some program--possibly a contrived and useless one--which nominally exercises each of the limits, at least individually. The authors acknowledge, in the published Rationale, that such a requirement is absurdly weak:

The Standard requires that an implementation be able to translate and execute some program that meets each of the stated limits. This criterion was felt to give a useful latitude to the implementor in meeting these limits. While a deficient implementation could probably contrive a program that meets this requirement, yet still succeed in being useless, the C89 Committee felt that such ingenuity would probably require more work than making something useful

I think they overestimated the "ingenuity" required, but I think the key point is that whether or not the Standard would regard as conforming an implementation that would e.g. allow a program to have one identifier that was 63 characters long and limited all other user identifiers to too characters, nobody who wanted to sell a compiler would impose such a limitation. Thus, while the Standard's definition of "Conforming C Implementation" isn't actually meaningful, it nonetheless establishes some baseline expectations for non-garbage-quality implementations.

As for the concept of "Conforming C Program", that term is defined to include any program that is accepted by at least one Conforming C Implementation somewhere in the universe. This is obviously too broad to be meaningful; I think the point was that the Committee wanted to avoid categorizing any useful programs as non-conforming. Again from the Rationale (italics original):

A strictly conforming program is another term for a maximally portable program. The goal is to give the programmer a fighting chance to make powerful C programs that are also highly portable, without seeming to demean perfectly useful C programs that happen not to be portable, thus the adverb strictly.

C implementations are expressly granted latitude to add extensions to the language, either syntactically or by defining behaviors in situations where the Standard imposes no requirements (typically processing constructs "in a documented fashion characteristic of the environment"), and Conforming (but not Strictly Conforming) C Programs may exploit such extensions. Although implementations are nominally required to produce a diagnostic in response to some such constructs, such a requirement would be satisfied by an implementation that unconditionally outputs: "Warning--this implementation doesn't bother producing diagnostics the author thinks are silly (other than this one)" and programmers would be free to ignore any diagnostics they think are silly.

It's important to recognize that many practical and useful C programs exploited useful constructs that were widely supported but not universally supportable. Had the Committee sought to characterize as deficient implementations for platforms that could't support such constructs, it would have been rejected by the makers of those platforms. Had it characterized as non-conforming programs that relied upon such constructs, it would have been soundly rejected by the programming community. Thus, as a compromise, it defined a category of "strict conformance" for programs that was sufficiently narrow that failure to meet it could seldom be viewed as a defect, and otherwise relied people wishing to sell compilers to recognize and satisfy the needs of programmers who would be using them--a philosophy that worked well when compiler writers' primary customers were programmers.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • Many thanks for the detailed answer. I could not understand why in C11 `conforming program` is defined through `conforming implementation` and `conforming implementation` is defined through `strictly conforming program`. This implies that A is defined though B, and B is defined through particular case of A. which is a recursive definition. Does the standard allow a recursive definitions? – pmor Jul 25 '21 at 19:50
  • I think that these terms should (shall!) be defined in the following (progressive) way: _conforming program -- a program that uses only those features of the language and library specified in this Standard_, _strictly conforming program -- a conforming program that does not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and does not exceed any minimum implementation limit_, _conforming implementation -- implementation that accepts any conforming program_. Can you comment on that? – pmor Jul 25 '21 at 19:51
  • @pmor: The reason C is useful is that it served not just as a language, but as a recipe for forming useful dialects suitable for low-level programming on a variety of platforms. I think it would be useful to have a standard for such dialects, which defines language constructs in terms of primitive actions, but then provides means by which programmers can invite optimizations which might affect program output or behavior in specified ways, for use in cases where the original and altered behaviors would both be acceptable. For example, one could specify that even on a platform where... – supercat Jul 25 '21 at 21:04
  • ...integer arithmetic uses quiet two's-complement wrapping semantics on overflow, one could specify that a compiler may at its leisure behave as though calculations were performed with wider types than specified, thus allowing e.g. `x*30/15` to be replaced with `x*2` even though that would change program behavior in case of overflow. When the Standard indicates that an implementation may process constructs that invoke UB "in a documented fashion characteristic of the environment", that wasn't an idle possibility--what made the language useful was that implementations intended for low-level... – supercat Jul 25 '21 at 21:08
  • ...programming would behave in ways that weren't anticipated by the Standard, but were characteristic of the environment. The problem is that some people on the Committee refused to have the Standard say anything that might be perceived as encouraging people to write non-portable programs, while others refused to have the Standard imply that there was anything wrong with non-portable programs. The only way to reconcile those is to no have the Standard say anything about non-portable programs, which unfortunately severely limits its usefulness. – supercat Jul 25 '21 at 21:11