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:
- ISO/IEC 9899:1990 plus TCs.
- ISO/IEC 9899:1990 + AM1 (effectively 9899:1995) plus TCs.
- ISO/IEC 9899:1999 plus TCs.
- 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.