"At least one" in the C specification to limit translation to the C standard

(This question was triggered by the answer to this previous question )

The C11 standard uses the following wording to discuss the complexity of the programs that the corresponding compiler must support:

5.2.4.1 Translation restrictions

An implementation must be able to translate and execute at least one program that contains at least one instance of each of the following limits:

...

  • 127 arguments in one function call

...

This “at least one” phrase seems curious to me, because it looks like a program that is compliant with standards, can impose arbitrary restrictions on most customs and still meet the requirements. For example, with the restriction of argument 63 for variational functions, but the limit is 127 for functions with explicit parameters. Or it is required that only functions with names beginning with "BIGARG_" can be called with more than 99 parameters. Or some other such restriction.

Even with potentially arbitrary restrictions, there may be some odd condition in which the restriction of argument 127 will be supported, so at least one program containing at least one instance of this limit can be translated and executed. It’s just that not all - or even most - programs that are approaching this limit will be supported.

Is there any justification for this particular phrase? Why is support for each program (in a different way) that obeys these restrictions clearly not required? Or is there some other mechanism that requires uniform support, for example, 127 arguments in function calls?

+5
source share
2 answers

Yes, an implementation can place arbitrary restrictions on the programs that it can process, although they still match the letter of the standard. But the goal of 5.2.4.1 is that the easiest way to meet your specific requirements is to maintain reasonable limits for all programs.

You can create one program that will process each of the translation limits defined in 5.2.4.1 (and this, for example, does not produce any output), and then write a “compiler” that recognizes this single program and creates an executable file that does equivalent to int main(void){} , rejecting every other program with a diagnostic message saying that it exceeds the implementation translation limits.

Such a compiler, of course, would be completely useless, so (as far as I know) no one bothered to create such a thing. (I thought about doing it myself, just for that.)

In practice, compiler developers want to create useful compilers that will correctly compile real C code.

Requirements 5.2.4.1 are designed in such a way that the easiest way to satisfy them (if you are writing a useful C compiler) is to impose as few actual limits as possible.

For example, the corresponding compiler should support 127 levels of nesting blocks for this mythical "one program." The easiest way to satisfy this requirement is to maintain arbitrary depth of nested blocks if the compiler uses dynamic data structures. In practice, the depth is not limited by the hard limit in the compiler source, but by the amount of memory available at compile time. (Or the compiler could use some internal fixed-size data structure that allows for exactly 127 levels, but it is probably easier to resolve dynamic sizes.)

You might think that it would be better if the standard imposed more “reasonable” requirements, so that the appropriate compiler should accept all programs that do not exceed certain specified limits. The problem is that such “reasonable” limits are extremely difficult to pinpoint. There will always be some programs that exceed the capabilities of the compiler - and the size or complexity of such programs depends on the internal data structures and algorithms used by the compiler, and on the ability of the particular system in which the compiler runs on. The standard could not cover such details or foresee what limitations might be “reasonable” for future systems.

+4
source

A standard cannot require implementation to accept all such compatible programs. Let's consider several restrictions, say, 127 levels of nesting of blocks and 511 identifiers with block volume. Now imagine a program with 127 levels of nesting blocks and 511 identifiers at each of these levels. Throw 63 symbolic characters in each identifier, and you have a huge program. An implementation that runs on a 16-bit microcomputer such as PDP-7 :) probably will not be able to handle it.

+3
source

Source: https://habr.com/ru/post/1244023/


All Articles