I'm looking for the most recent versions of modern C compilers which were/are targeting DOS 8086, also running on DOS 8086 (16-bit). I'm mostly interested in production-ready C compilers, rather than hobby projects (possibly many bugs yet to be discovered).
By modern I mean:
- support for ANSI C (C89) source files
- support for generating small model and large model DOS
.exeprograms
See in my answer what I've found to work.
I'm aware of the following C compilers, but they are not answers to my question, because they have some required features missing:
LSI C-86 3.30c released on 1993-08-23: It doesn't support the large memory model.
DeSmet C 3.1h (1988) and DeSmet C 3.1N (1992): It seems to support ANSI C and the large memory model. (Compile hello.c using the small model:
c88 hello;bind hello. Compile hello.c using the large model:c88 hello b;bbind hello) But it doesn't support the unsigned long type. Also I wasn't able to define a function which takes variable number of arguments (va_list args;doesn't compile). Also compilation breaks in weird ways, e.g.foo->field = 42;doesn't compile (but(*foo).field = 42;does), but then in the next line it compiles. I've given up on this compiler, it has too many bugs.PCC 1.2d: It has the same engine as DeSmet C 2.51. It doesn't support the large memory model.
HI-TECH Software Pacific C 7.51 released on 1996-01-20 (and re-released with a less restrictive license on 2000-05-10): (1) the compiler is generating some useless overflow warnings for numbers between -40 and 40, so there may be many code generation bugs, probably not worth the effort; (2) the compiler is running out of memory for my tools which Borland Turbo C++ 1.01, Borland C++ 2.0 and Microsoft C 6.00a can compile easily. I've given up on it.
Manx Software Systems Aztec C86 5.2a released on 1992-11-17. It isn't able to compile my tools, the assembler fails with out-of-memory error. Borland C++, Microsoft C and Zortech C++ are all able to compile the program successfully. Also with the
-ansiflag it displays some weird error messages (all other modern and all the mentioned old C compilers succeed), I'm not sure how easy it is to work around the errors. It does support the small and large models.SubC 2014-05-25 released on 2014-05-25. It doesn't support many C language features, e.g. typedef. The port running on DOS 8086 is experimental.
I'm aware of the following C compilers, but they are not answers to my question, because they don't run on DOS 8086:
OpenWatcom: I've successfully compiled C code targeting DOS 8086 with the most recent build 2022-11-22 on DOSBox with 5 MiB of memory. Arguably OpenWatcom is the most modern C/C++ compiler still targeting DOS 8086. However, the DOS port of the compiler itself runs in 32-bit protected mode, and thus needs a 386 processor. I'm not using the DOS port though, the native ports to my laptop are faster, and they produce the same DOS program.
GCC: It doesn't support 8086 as a target.
DJGPP: It doesn't support 8086 as a target.
gcc-ia16. Supports multiple memory models (e.g.
-mcmodel=smalland-mcmodel=large) for DOS 8086.Clang: It doesn't support 8086 as a target.
Microsoft Visual C++: It doesn't support 8086 as a target. The last Microsoft compiler with DOS 8086 as a target was Microsoft C++ 8.00c.
Borland C++ Builder: It doesn't support 8086 as a target.
TinyCC (TCC): It doesn't support 8086 as a target.
Digital Mars C/C++ 8.57 released on 2022-05-14: The compiler
.exefiles are for Win32, they don't run on DOS 8086. However, it supports DOS 8086 as a target (at least for compiling C code to an OMF .obj file), with multiple memory models (e.g.dmc -msanddmc -ml).Smaller C 1.0.1 released on 2021-09-14: Even the DOS real mode compiler tools (e.g.
bind/smlrc.exe) need a 386 CPU.Symantec C/C++: It supports DOS 8086 as a target (at least for compiling C code to an OMF .obj file), with multiple memory models (e.g.
sc -msandsc -ml). This is the successor of Zortech C++, and the compiler executable programs probably run in protected mode, thus they need a 386 CPU. Maybe version 6.0 still contains DOS 8086 programs, I have to try. In version 6.1 there is thesc -b ...command-line flag, but the correspondingscc.exe(C compiler for DOS 8086) andscpp.exe(C++ compiler for DOS 8086) are not provided, probably they were never released. The protected mode programssccxandscppx.exerun in protected mode, and need a 386 CPU (they work in DOSBox with 2 MiB of memory). Release history:- Symantec C++ Professional 6.0 was released in 1993-09.
- Symantec C++ Professional 6.1 was released in 1993-12.
- Symantec C++ 7.0 for Windows was released in 1995-07.
- Symantec C++ 7.2 for Windows 95, Windows NT 3.5, Windows 3.1 and DOS was released in 1995-10.
- Symantec C++ 7.50 was released in 1997.
Is there any C compiler I've missed? Maybe there is a much more recent (than 1992) minimalistic C compiler.
ztc -b ..., then it works on DOS 8086. Without the-bflag, it needs a 386 CPU on DOS. I'm updating my answer. – pts Nov 25 '22 at 10:44-ansiflag it displays some weird error messages (all other modern and all the mentioned old C compilers succeed), I'm not sure how easy it is to work around the errors. It does support the small and large models, and it can compile a hello-world program successfully. – pts Mar 28 '23 at 19:41wcc.exefor DOS 8086. I think the compiler code size is too large, there won't be enough of the 635 KiB of memory remaining for the code to be compiled. Earlier versions were smaller. – pts Apr 06 '23 at 14:29__nearand__farqualifiers, with the semantics that implementations need not do anything with them, but systems may have an implementation-defined limit on the amount of storage that's qualifiednear, and afarmallocfunction which returns a far-qualified pointer might have access to storage which is only accessible via far-qualified pointer (andfarmemcpy,farmemmove, etc.), Portable code could selectively define macros likenear3,near2,etc.. that could be defined as__nearor nothing based upon... – supercat May 26 '23 at 14:31near, see if things fit, then undefine one of them, see if things fit, etc. Even when targeting something like the 68000 or ARM, the efficiency of code that uses many file-scope variables could be improved by having a register dedicated to holding the start of "near" storage, and using register-displacement addressing to access such things (classic Apple Macintosh used A5 for that purpose). – supercat May 26 '23 at 14:35(0x1E-x)as a useful expression that subtracts x from thirty, while gcc "correctly" requires that a programmer wanting that meaning must insert whitespace after theE. On the flip side, gcc and clang generate nonsensical code in corner cases where the Standard is unambiguous, but behaving as described by the Standard would block... – supercat May 26 '23 at 18:56