Search code examples
ccompiler-constructionstandardsfreestanding

What are the differences between the various WG14 C standards for freestanding implementations?


How would compilers implementing the freestanding portion of each different standard below have to differ? What would be the fewest number of modes (specified by command line flags, for example) required to support all of them?

  1. ISO/IEC 9899:1990
  2. ISO/IEC 9899:1990 + ISO/IEC 9899 TCOR1
  3. ISO/IEC 9899:1990 + ISO/IEC 9899 TCOR1 + ISO/IEC 9899 AM1
  4. ISO/IEC 9899:1990 + ISO/IEC 9899 TCOR1 + ISO/IEC 9899 AM1 + ISO/IEC 9899 TCOR2
  5. ISO/IEC 9899:1999
  6. ISO/IEC 9899:1999 + ISO/IEC 9899:1999 Cor. 1:2001(E)
  7. ISO/IEC 9899:1999 + ISO/IEC 9899:1999 Cor. 1:2001(E) + ISO/IEC 9899:1999 Cor. 2:2004(E)
  8. ISO/IEC 9899:1999 + ISO/IEC 9899:1999 Cor. 1:2001(E) + ISO/IEC 9899:1999 Cor. 2:2004(E) + ISO/IEC 9899:1999 Cor. 3:2007(E)
  9. ISO/IEC 9899:2011

Solution

  • The TCs (technical corrigenda or technical corrections) should be treated as part of the corresponding base standard. So, you really have 4 possible standards to deal with:

    1. ISO/IEC 9899:1990 plus TCs.
    2. ISO/IEC 9899:1990 + AM1 (effectively 9899:1995) plus TCs.
    3. ISO/IEC 9899:1999 plus TCs.
    4. ISO/IEC 9899:2011

    The Amendment 1 for C90 added new headers and functions for wide character and multi-byte character sets, so it contained truly new standard material. The technical corrigenda fix issues in the standard wording, clarifying what needs to be clarified, and correcting technical errors in the document.

    So, I would suggest that those four modes would be sufficient:

    • -std=c90
    • -std=c95
    • -std=c99
    • -std=c11

    Or, if we are going to pay attention to the mistakes that led to the Y2K problems, then:

    • -std=c1990
    • -std=c1995
    • -std=c1999
    • -std=c2011

    (One advantage of this is that the newest standard has the highest number once more!)


    For freestanding implementations, there are few differences in the four headers that are required:

    • <stddef.h>
    • <limits.h>
    • <float.h>
    • <stdarg.h>

    There was an extra macro/function, va_copy(), added to <stdarg.h> in C99.

    Correction

    I just checked the relevant parts of C99, and there are a number of extra headers required for a freestanding implementation in C99:

    §4 Conformance

    ¶6 The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program that does not use complex types and in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, and <stdint.h>. A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.3)

    3) This implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this International Standard.

    §5.1.2.1 Freestanding environment

    ¶1 In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.

    ¶2 The effect of program termination in a freestanding environment is implementation defined.


    Otherwise, the main changes occurred in the core language in C99 - things like the new types (long long), new initialization notations, and VLAs, and so on. From this perspective, AM1 (C95) didn't change anything for a freestanding implementation (unless digraphs were added then) because the main changes were in new headers that are not required in a freestanding implementation.

    Hosted implementations face many more issues because the library support was fairly extensively modified between C90 and C99.


    Did any of the changes for freestanding implementations break backwards compatability? In other words, if I have a strictly freestanding C{1990,1995,1999} conforming program, will it necessarily compile and work as expected on a conforming C11 implementation?

    I'm not aware of any backwards compatibility issues for freestanding as opposed to hosted implementations. With C99, the 'implicit int' rules are officially gone - you should declare functions before using them and the return type should be explicitly int (so, for example, a simple main() is no longer officially valid; you should write int main() or, better, int main(void) or similar). But these are general changes between C90 (C95) and C99 - not peculiar to freestanding implementations. (And yes, I am aware that a freestanding implementation need not require a function main() as the start point.) If your code is 'good' and has functions declared or defined with prototypes before use and no implicit int types (and all functions defined using prototype notation would be strongly recommended), then what was good for a C90 freestanding program will work for C99 or C11.