Last update Sun Aug 7 02:11:45 2022

DMC: Compiler

dmc is a one-step program to compile and link C++, C and ASM files. sc is the same program with a different name, kept for backwards compatibility.


Arguments to DMC can be presented in any order, if any arguments conflict, the rightmost argument takes precedence. The command line to DMC takes the form:

dmc { { @responsefile } { file } { switches } }

where the { } means "repeated 0 or more times". DMC with no arguments prints a short help file to stdout.


DMC looks in the directory where dmc.exe resides for the file sc.ini. sc.ini is a text file, containing environment variable settings in a similar manner as they might be set in AUTOEXEC.BAT:

;Comments are lines where the first non-blank
;character is a ';'
CFLAGS=-v -w

;Note that %PATH% gets replaced by the previous
;value of the environment variable PATH.

The special environment variable @P gets replaced with the path to where the sc.ini file resides. For instance, the above can be replaced with (if sc.ini is in c:\dm\bin):

CFLAGS=-v -w

which makes the settings in sc.ini independent of where the DMC directory tree is installed.

If sc.ini is not there, no error results. This feature is useful for avoiding cluttering up AUTOEXEC.BAT with environment variable settings. Not only that, it will make running DMC independent of any existing environment variables set for other tools.

The environment settings in sc.ini do not prefix, augment, or append any existing settings in the environment. They replace the environment settings for the duration of running the IDDE or the compiler. For example, to use sc.ini to append an INCLUDE path to the existing INCLUDE path, it can be written as:


How DMC.EXE Searches For Programs

DMC first searches in the directory from where DMC.EXE was found. If the programs are not found there, then the PATH is searched.

Environment Variables

DMC uses the following environment variables, either set at the console command line prompt or in the file sc.ini:

If it is set, it behaves as if the first argument to DMC is @CFLAGS. CFLAGS is a convenient way to temporarily set switches to the compiler without modifying batch files or makefiles.
Path to search for #include'd files.
Search path for library files.
Search path for executable files if they are not found in the same directory where DMC resides.


responsefile is searched for as an environment variable name, and if not found, as a file name. If it is found, the text of the environment variable or file name is inserted in the command line as if it were part of the command line. In this way, the command line length limit of many operating systems can be circumvented. If responsefile is not found, no text is inserted.
A file name. If no extension is given, the following extensions are tried in the order given to see if there is a match:
  1. .c
  2. .cpp
  3. .cxx
  4. .cc
  5. .c++
  6. .asm
  7. .s
  8. .rc

The extension of the file determines what is done with the file.

Extension Action
no extension  
any other extension  
.c Run C compiler
.c++ Run C++ compiler
.s Run assembler
.a Include file as a library to the linker
.o Include file as an object file to the linker
.dll Include file as the output file to the linker
.def Include file as the module definition file to the linker
.rc Run resource compiler
.res Include file as the resource file to linker


Set alignment of struct members.
-a, -a1
align on byte boundaries
(default) use alignment indicated by selection of memory model
align on 2 byte boundaries (default for 16 bit models)
align on 4 byte boundaries (default for DOSX)
align on 8 byte boundaries (default for Win32)

Alignment can also be controlled within a source file by using #pragma pack().


Strict ANSI C/C++, which disables all non-ANSI extensions. This is useful for compiling ANSI test suites, and for verifying that code will compile in a strict ANSI environment.

Effects on C and C++:

  • Predefined macros that do not start with a single or double underscore are not defined.
  • The macro __STDC__ is defined and set to 1.
  • Trigraphs are enabled.
  • Floating point comparison operators <>=, !<>=, <>, !>, !>=, !< !<= !<> are disabled.
  • Binary integer constants (such as 0b10110) are disabled.
  • Keywords beginning with a single _ are disabled.
  • asm, cdecl, far, huge, near, pascal keywords are disabled.
  • '$' is not allowed as an identifier character.
  • /p (pascal strings) are disabled.
  • At least one hex number must follow a \x escape sequence.
  • Hex numbers specified with a trailing h are disabled.
  • MASM-style hexadecimal constants (012h, 1E3H, etc.) are disallowed.
  • Blank macro arguments not allowed.
  • #defines that redefine macros must be preceded by #undefs
  • Arithmetic operations on function pointers are invalid
  • Text at the end of a preprocessor directive is an error, so, #endif COMMENT would need to be #endif /* COMMENT*/.
  • Empty member lists in enums, or member lists with a trailing comma (,) become syntax errors.
  • Casts and sizeof() are invalid in preprocessor expressions
  • #ident is disallowed.
  • The compiler no longer recognizes the following extended keywords: _asm, _cdecl, _declspec, _export, _far, _seg16, _fastcall, _fortran, _handle, _huge, _interrupt, _loadadds, _near, _pascal, _saveregs, _stdcall, _syscall. For ANSI compatibility, use the "__" (double-underscore) versions of these keywords. The versions of these keywords without leading underscores are also not recognized with -A.
  • It is an error to have an unrecognized preprocessor directive in a false conditional block.

Effects on C:

  • Type checking on default integral promotions is more strict.
  • Source files must end with a newline character (\n).

Effects on C++:

  • RTTI support is enabled.
  • Exception handling support is enabled.
  • overload keyword is disabled
  • implicit conversion of void* to pointers of other types is invalid
  • Syntax like char abc[4] = "1234"; where there is no room for the trailing 0 is invalid.
  • Anonymous unions with file scope must be static
  • Member functions can't be declared as static outside a class definition
  • static class data members must be defined somewhere in the program source.
  • Overloading of operator new[] and operator delete[] is enabled.
  • Floating types for non-type template-parameters are disallowed.
turn off -A
Enable overloading of operator new[] and operator delete[] separate from operator new and operator delete. This also predefines the macro _ENABLE_ARRAYNEW. -A (ANSI compatibility) also enables -Aa.
enable bool as a built-in type, with values true and false
Revert to single level name lookup, as opposed to the standard conforming two level lookup.

Enable exception handling

Because code generated for exception handling (EH) is not quite as good ('this' pointers are not placed in registers, tables are generated), the default is that EH is not enabled. To enable EH, compile with the -Ae switch. Compiling for ANSI C++ (-A) will also enable exception handling support.

To compile C code that is to be mixed into C++ code that handles exceptions, compile the C code with -Ae also.

Objects compiled with -Ae may be linked with objects compiled without -Ae, provided that no exceptions are thrown in the resulting program that are not handled entirely within objects compiled with -Ae.

The tables are generated in the same segment using the same rules as the virtual function pointer tables. Using -NV will place the tables in far segments (for 16 bit memory models).


Enable RTTI (Run Time Type Identification) support. RTTI is off by default because RTTI adds space and time to executables. RTTI works by adding a new member to the virtual function table (vtbl[]), a pointer to the type info for that struct. This means that classes can no longer share vtbl[]s (an optimization done by default). The type info pointer is at a negative offset to the start of the vtbl[], this is to retain object model compatibility with the Microsoft Object Model (which does not support RTTI).

For link compatibility with Microsoft C++ compiled DLLs, but still using RTTI, compile with -ER:

  • All modules that use typeid()
  • All modules that use dynamic_cast
  • All modules that compile the bodies of constructors for classes that need to support RTTI

The reason for this is that the vptr member of the class needs to be set to a virtual function table that has the RTTI type info pointer in it. A vtbl[] with RTTI type info has a different mangled name than one without, this helps to get everything linked up right.

Virtual function call compatibility is not affected by RTTI.

It is best to avoid using RTTI on classes that are pulled in from a .LIB, .OBJ or .DLL where they were compiled with a different compiler.

Enable wchar_t as a built-in type
Run X versions of compiler passes (obsolete, ignored)
-bn Run NT console app versions of compiler passes (obsolete, ignored)
-B, -Be, -Bf, -Bg, -Bj
Causes compiler error messages to be printed in the various languages. This switch would be most conveniently be set in the CFLAGS environment variable or sc.ini file.
-B English
-Be English
-Bf French
-Bg German
-Bj Japanese
-c Compile only, do not link executable.
-cpp Assume source files are C++
Causes DMC to run the C++ compiler rather than the C compiler on source files with a .c extension or an unrecognized extension. To separately precompile a .h file for C++, use the -cpp switch.
-C Disable inline function expansion
-C- (default) enable inline expansion

Prevents the inline expansion of functions with the inline storage class. This can be useful in sorting out a complex tangle of inlined functions when debugging. It can also result in smaller (but slower) generated executables. It has no effect on compiler intrinsic functions like strcmp() and memcpy(). If these functions should not be inlined, use the portable method:

#undef strcmp   /* use runtime library version of strcmp */
-cod Generate .cod (assembler output) file
Causes obj2asm to be run on the .obj file output from the compiler to generate a .cod file showing the assembly code generated. Using this along with the -gl switch will generate a mixed source/assembly .cod file.
-d Generate dependency information

If file.c is being compiled, then file.dep will be created. It will contain a list of #include files that file.obj depends on. The line in the makefile can be written as:

file.obj : $(file.dep) file.c
    dmc -c file -d
-D[macro[=text]] define macro
Equivalent to #define DEBUG 1
Will also enable the debug statements and debug declarations.
Equivalent to #define macro 1
Equivalent to #define macro
Equivalent to #define macro text

The '#' character can be used instead of '='. To embed white space in the macro's text, enclose the entire text in double ("") or single quotation marks (''), as in -Dmacro="this is a string", which is equivalent to:

#define macro "this is a string"
-e show results of preprocessor
Shows the effects of the preprocessor in error messages and in the list file. To verify that macros are expanding as expected, use the options -e and -l together.
-EC do not elide comments
For SPP: leave comments in preprocessed output.
-EH obsolete - use -Ae
-EL #line directives not output
For SPP: do not add #line directives into the output.
-ER obsolete - use -Ar
-f generate IEEE 754 inline 8087 code

For 16 bit code and the DOSX memory model, the compiler by default generates code assuming a numeric coprocessor does not exist. This code is less efficient than if numeric coprocessor code is generated directly. -f will cause numeric coprocessor code to be generated directly, but the code will not run on machines without a coprocessor.

Win32 implementations have an emulator for the numeric coprocessor, so -f is the default for the -mn memory model.

-fd generate IEEE 754 inline 8087 code with workaround for FDIV bug

Some old Pentium CPU chips have a bug when executing FDIV instructions. When not generating inline 8087 code, the floating point emulator in the runtime library automatically accounts and corrects for the errors. When generating inline 8087 code, the -fd switch will call a runtime library function for FDIV instead of generating an FDIV instruction directly. This results in code that is a little larger and slower than -f code, but it won't be subject to FDIV bugs. Do not use -fd if the code will never be run on a Pentium.

No Pentium Pro or Pentium MMX chips have this bug.

-ff fast inline 8087 code

The difference between -f and -ff is that with -ff floating point comparisons with NaN (Not a Number) are not done exactly according to IEEE 754. Normally, this does not matter, so -ff will yield faster code. Other compilers for Intel CPUs do not correctly generate code for NaN comparisons, so to compare Digital Mars floating point code performance with that of other compilers, use the -ff switch.

-ff will also cause the folding of floating point constants even if they would generate an exception. For example, 0.0/0.0 will be folded at compile time instead of at runtime.

Use -ff -fd in combination to get fast inline code with the FDIV bug workaround.

-g{-345dfghlpst} generate debug info

There are several ways of generating debug info for a compiled file. If the compiler always generated debug info for all types, the .OBJ files would be huge and the linker would have a lot of work to do to remove all the redundant information. Ideally, debug info is generated only once for each type across all compilation units.

The default, -g, only generates debug info for types of variables that are actually used by a module. This greatly cuts down on the size of the object file. In addition, since C++ class hierarchies tend to be very complex, -g generates class debugging information only for classes for which a corresponding virtual function table is generated.

-g is the right choice for programs that do not reference libraries or DLL's for which type info is needed.

Sometimes, though, if part of a class implementation lies inside a DLL, the debug info for that class may never get generated. Thus, the -gf flag exists to cause full debug info to be generated for each class that is reference by generated code.

Even -gf can get a bit problematic, since it can cause large quantities of debug info to be generated. It also never generates debug info for classes that only may be referenced in a linked-in library or DLL which were compiled separately without debug info.

-gh causes debug info to be generated for all global structs and typedefs, regardless of if they are referenced or not. One could just use -gh for all compilations, and it will work, but it will be a bit slow.

A better solution is to use -g for all the modules in the program. Then, create a special file TOTAL.C, which has a #include statement in it for each header that references a library or DLL. Compile TOTAL.C with -gh (and the other memory model, etc. switches), and TOTAL.OBJ will contain all the debug info needed for those DLLs and libraries. This will minimize compile/link times, which is important for fast development turnaround.

OBJ2ASM can be run on any .OBJ file, and it will format and pretty-print any debug info found in the file. This is handy to see what the compiler is doing.

-g Generate line info and debug info for types of referenced variables.
Equivalent to -gsl. Type info for typedefs and enums is not generated.
-g- turn off debug output
-g3 Generate Codeview 3 format debug info.
This is useful to support old debuggers, but is now obsolete. It is no longer supported.
-g4 Generate Codeview 4 format debug info.
This is the default.
-g5 Generate Digital Mars format.
-gd Dynamic C++ type info (obsolete)
-gf Generate debug info for full class hierarchy for any referenced classes.
-gg Make static functions global.

This is useful when tools that read .MAP files are needed, since only global function names will appear in the .MAP file.

If a C++ inline function is outlined, it still remains static, even with the -gg option enabled. This is because name collisions in this case are difficult to prevent. A C++ inline function is outlined if:

  • It is virtual.
  • The address of the function is taken.
  • The function cannot be reduced to a simple expression; that is, it contains do, while, for, or switch constructs.
-gh Generate debug info for all global structs, enums, and typedefs.
This is done automatically if -g is thrown with -HF.
-gl Generate line number debug info only.
This is useful when a .cod file output is desired, as then the source code will be intermixed in with the compiled output. It is also useful when working with debuggers that derive all their debug info from .MAP files.
-gp generate pointer validations

Generates code to call the function __ptrchk(void *p) for each pointer dereference. p is always a far pointer for 16 bit memory models, and always a near pointer for 32 bit memory models.

__ptrchk must preserve all registers, and must pop its parameter prior to returning (pascal calling sequence). These measures minimize the code expansion resulting from using -gp. Thus, __ptrchk must be written in assembler or inline assembler.

__ptrchk is intended for use by a memory debugger. The idea is that __ptrchk validates the pointer. If the pointer is not valid, it notifies the user at the source of the problem.

There is a default version of __ptrchk in the runtime library.

-gs symbol info only (do not generate line number info)
-gt Generate trace prolog/epilog for use with the Digital Mars Trace package.

Adds a call to a user-defined function to the prolog and epilog of each function. The function calls generated are:

void __far _trace_pro_n(void) // Prolog for near functions
void __far _trace_pro_f(void) // Prolog for far functions
void __far _trace_epi_n(void) // Epilog for near functions
void __far _trace_epi_f(void) // Epilog for far functions

The code for these functions must be provided; typically, they would be used to generate debugging information to support profiling. The functions must preserve all registers and, therefore, must be in assembly language.

The prolog function is called after the stack frame is set up, and the epilog is called just before the stack frame is destroyed.

Implementations of these functions are provided in the runtime library that implement dynamic execution profiling.

Different instances of -g can be combined sequentially. For example, -g3h is equivalent to "-g3 -gh." If combinations conflict, the compiler uses the last option specified. For example, -g -g4 generates CV4 format information; -g4 -g3 generates CV3 format information.

-GTnnnn set data threshold to nnnn

In large data models arrays and structs that are larger than nnnn are allocated in far data segments rather than DGROUP.

Allocate arrays and structs larger than nnnn to far data segments.
Default (all static data is placed in DGROUP).

The -GTnnnn switch is ignored for near data models (t,s,m) and for all 32 bit memory models.

If using -GT, use the same value for all modules. For .ASM modules, be careful when referencing global data whether it is in DGROUP or in a far data segment. The symptoms of getting this wrong are frame errors from the linker.

Note that if -GT is used, arrays declared with empty [] like:

extern int array[];

are assumed to be far. If they actually are near, declare them using the dimension, or mark them explicitly as __near.

Always be sure to use the same nnnn threshold value for all modules compiled with -GT.

-H use precompiled headers (ph)

When the compiler encounters a #include statement for filename.h, it looks instead for filename.sym in the current directory. filename.sym is the precompiled version of the header file.

-H also implies -HO (include files only once).

-H- Do not use precompiled headers (default)
-HC Do not cache precompiled headers in memory.
-HC- Cache precompiled headers in memory (default).

In the IDDE, by default, when precompiled headers are read in from disk, they are cached in memory so when subsequent files are compiled, the precompiled header is read from memory rather than from disk. When there is not a lot of physical memory, however, this can cause a lot of page swapping, resulting in decreased compile speeds. Thus, the -HC switch will turn off caching them.

The -HC switch does not apply to -HX precompiled headers, which are always cached in memory for IDDE compiles. The -HC switch is ignored for the command line compiler, which always reads precompiled headers from disk.

-HDdirectory Set precompiled header directory
If the precompiled header directory for use with the -H, -HF and -HX switches is not the current directory, use -HD to set the directory to use. This is useful when the precompiled headers go to a fast ram disk.
-HF[filename[.sym]] write precompiled header to filename.sym.

-HF is used to generate a precompiled header, -H is used to compile files that will be using that precompiled header. The default output file name is the name of the source file with a .sym extension.

The filename.obj file that is also generated should be linked in as well, as contains code and data generated when building the precompiled header. If -g is thrown, the .obj file will contain all the debug info for the header file(s).

-HHfilename Read precompiled header from filename.
A precompiled header's filename is normally generated from the name of the first #include file. This switch will set an alternate file name to be used.
-HIfilename #include filename

Before compiling the source files on the command line, #include the file filename along with them. Using this option is like adding #include filename to the beginning of each source file in the compilation.

This option is especially useful for including a precompiled header at the beginning of all the source files.

Set address to use for memory mapped files. address is in hex.
-HO Include header files only once
-HO- (default) turn off -HO

Normally, include files are read and parsed each time they are encountered. With -HO, include files are read and parsed only the first time they are encountered, and #include directives for that file are ignored if they appear again. This can result in faster compiling.

An alternative is to include the directive

#pragma once

in each include file that will never need to be parsed more than once.

-HPnn Set size of memory pool in megabytes
Under rare cases, the compiler may exit with an message about being out of memory. The size of the memory pool can be set to nn megabytes with this switch. nn should be greater than 30.
-HS only search -Ipath directories
Directs the compiler to search for #included header files only along the path specified by the -I switch. The current directory and the directory specified by the INCLUDE environment variable are not searched.
-HX Use automatic precompiled headers

Automatically generate and use a precompiled header named scph.sym. The precompiled header is generated if it does not exist or if any of the header files in it are newer than the scph.sym file.

The scph.sym file is placed in the current directory by default. The -HD switch sets an alternate directory for it.

-Ipath Set search path for include files

Searches for #include files along the specified path. Paths may end in a \. Multiple paths can be specified by separating them with a ';'. For example:

Switch Search
-Iabc Subdirectory abc
-Id: Default directory in drive d:
-Iabc;d: Both of above directories
-Ig:\cbx\include\ Directory g:\cbx\include
-I. Current directory
-I\ Root directory
-j[0|1|2] Asian language characters

Asian language character sets include double byte characters, where certain prefix bytes mean that the following byte forms part of the character. Asian language characters can appear in "" strings, in '' character literals, and in comments.

-j, -j0 Japanese
-j1 Taiwanese and Chinese
-j2 Korean
-j- no Asian language characters

When the compiler is run under Win32, the switches correspond to the following operating system locale code pages:

-j0 .932
-j1 .936
-j2 .949

These locales determine which bytes are the initial bytes of a multibyte sequence, and control how strings are converted to Unicode strings. If those locales are not supported by the operating system installed on your machine, or the DOS native version of the compiler is running, the lead byte of a multibyte character sequence is:

switch language prefix bytes
-j0 Japanese 0x81..0x9F and 0xE0..0xFC
-j1 Taiwanese and Chinese 0x81..0xFC
-j2 Korean 0x81..0xFD

and the conversion to Unicode is done simply by 0 extending a regular character and stuffing a multibyte sequence into 16 bits.

The -j switch is obsolete. The #pragma setlocale() directive is a superior solution.

-Jb disable empty base class optimization

The "empty base class optimization" causes base classes with no members to add no size to the derived class. Compilers 8.27 and earlier would add 1 to 4 bytes of size per empty base class (depending on alignment). Eliminating this can result in significant performance gains with STL.

For link compatibility with code compiled with compilers 8.27 and earlier that used empty base classes, the -Jb flag will help. Alternatively, add a char reserved; data member to the empty base class definition, which will cause it to have the same storage layout as earlier compilers.

-Jm relaxed type checking
-Jm- strict type checking (default)

Use for legacy C code which relied on the loose type checking of older C compilers. Do not use -Jm for new code development.

-Jm is ignored for C++ compilations, since C++ is heavily dependent on strong type checking.

-Ju char and unsigned char are the same type (unsigned char)
-Ju- (default) char and unsigned char are different types

This is useful in compiling some old legacy C code where the author arbitrarilly mixed up using char and unsigned char types. It is equivalent to:

#define char unsigned char

-Ju does not affect the behavior of runtime library functions like strcmp(), which always behave as if chars are signed.

Do not use -Ju for new code development.

Using -Ju causes all sorts of problems in C++ code, primarily goofing up overloading based on char types. Using -Ju for C++ is not recommended.

-J char promotions are unsigned
-J- char promotions are signed (default)

This affects whether objects of type char are sign-extended or zero- extended when being promoted from char to a larger type. It does not affect the signed char or unsigned char types. char is still a type distinct from unsigned char and signed char.

If code is sensitive to -J or -J-, then it is non-portable, and should be carefully checked to replace the sensitive types with signed char or unsigned char as needed. For instance:

char c;
int i = c;

Should be replace with (if it matters):

signed char c;
int i = c;


unsigned char c;
int i = c;


char c;
int i = (signed char) c;
int i = (unsigned char) c;
int i = c & 0xFF;

-J does not affect the behavior of runtime library functions like strcmp(), which always behave as if chars are signed.

-J causes the macro

#define _CHAR_UNSIGNED 1

to be defined.

-l[listfile] Generate source listing file

Generates a source listing file with the name listfile. listfile defaults to being the name of the input file with the extension .lst added. To show the effects of the preprocessor in this file, specify the -e option also. The compiler then inserts error messages and line numbers into the listing file.

There is no space between -l and listfile.

-L Using non-Digital Mars linker
Digital Mars linker has some extra features in them (like support for long command lines), -L means a non-Digital Mars linker will be run so those features cannot be used.
-Llinker Use linker linker instead of default.

This is useful if a special linker is being used, or if the linker is not on the PATH or in the directory where dmc resides.

For example, -L\path\mylink tells the compiler to run the MYLINK linker in the \path directory.

-L/switch Pass /switch to linker.

For example, this command:

dmc test -L/packcode -L\test\prog

adds the option /packcode and the library search path \test\prog to the linker's command line.

-Masm specify assembler to use

MASM is normally the assembler called by dmc when an assembler source file needs to be assembled. Use -M to specify an alternate assembler asm.

For example, -M\path\masm tells the compiler to run the MASM in the \path directory.

-M/switch Pass /switch to assembler
-m[tsmclvfnrpxz][do][w][u] Select memory model
16 Bit Models
t Tiny: small model program linked specially to create .COM file
s Small: small code and data (default)
m Medium: large code, small data
c Compact:small code, large data
l Large: large code and data
v VCM (Virtual Code Manager) (obsolete)
r Rational Systems 16 bit DOS Extender
z Zortech ZPM 16 bit DOS Extender (obsolete)
32 Bit Models
f OS/2 2.0 32 bit flat model (not supported)
n Win32 32 bit flat model (default)
p Pharlap 32 bit DOS Extender (obsolete)
x DOSX 32 bit DOS Extender (obsolete)

Memory Model Modifiers

d DOS 16 bit (default)
o OS2 16 bit (obsolete)
Indicates code will be targeted towards an OS/2 16 bit executable.
w assume SS != DS
Use the w flag in combination with the -m option to make sure that the stack segment (SS) is not equal to the data segment (DS). Certain types of executables require that the DS and the SS be different. These are:
  • 16-bit dynamic link libraries (DLLs)
  • 16-bit multithreaded code
u reload DS

Use the u flag in combination with the -m option to instruct the compiler to always reload DS from the current value of DGROUP upon function entry. Note that u does not also imply that the DS and the SS are different (use w for that, as described above).

For 16 bit Windows code, use the -W switches instead of the w or u modifiers to the -m flag. This will prevent order dependencies, since a -W switch appearing after a -m switch will override the w or u modifiers on the -m switch, and vice versa.

-Nc function level linking
This causes each global or static function to be placed into its own COMDAT record. This will enable function level linking. Function level linking means that only functions actually referenced by other code will be pulled in and placed in the final executable.
-NC don't generate COMDATs (obsolete)
Avoid using this switch. It is now obsolete, since current linkers now all support COMDAT records.
-ND compile and link with DLL version of runtime library
Defines and sets _MT and _DLL to one. Changes the embedded RTL name from SNN.LIB to SND.LIB. This must be used only with the Win32 memory model (-mn). The DLL version of the runtime library is \dm\bin\sccrt70.dll.
-NF ignore extended keywords
The keywords __far, __huge, __loadds, __interrupt, __handle are ignored. (This is the default for N and F memory models.) -NF can be useful for compiling old 16 bit code for the x or p memory models.
-NL Do not embed default library record
The compiler normally embeds in the object file a record indicating the default runtime library to be linked in. -NL suppresses this embedding. This is useful when:
  • Compiling code that will go into a library, getting rid of all those records can result in a substantial reduction in library size.
  • Compiling code that will be linked with code generated by other compilers.
dashCapNCapLlibfile, -NLlibfile
Embed the filename libfile.lib into the object file instead of the default.
-Ns place expression strings in code seg

Places strings that appear in expressions into the code segment rather than the data segment. Expression strings are always placed anyway in the code segment if the type of the expression is __cs*. The -Ns switch will place expression strings into the code segment that are typed as far pointers (the default in large data models).

-Ns is ignored for FLAT memory models (-mn, -mf).

-Ns is useful for 16 bit Windows programs to reduce DGROUP usage. Note that strings placed in the code segment cannot be written to. To write into a string and use -Ns, make the particular writable string a static array.

-Ns does not place strings in statically initialized data structures into the code segment.

-NS new code seg for each function

Causes a new code segment to be started each time a global far function is encountered. The name of the segment is the name of the function, with _TEXT appended.

Because near functions cannot cross segment boundaries, all near functions must immediately follow any global functions that call them and cannot be called by more than one global function.

-Nt use old template name mangling scheme (obsolete)
By default, the compiler generates VC compatible name mangling. For compatibility with object code with pre-version 7.2 compilers, the -Nt switch enables the old template mangling scheme.
-NTname Set code segment name to name.
Sets code segment name, rather than using the default, module_TEXT.
-NV Put virtual function tables in far data segments.

Put virtual function tables in far data segments. by default. The default behavior is to put vtbls in the code segment for the Compact and Large memory models and for all 32-bit data models. For programs compiled with the Tiny, Small, or Medium models, the compiler places vtbls in DGROUP.

This option is useful for saving code space in Compact and Large model programs.

Borland C++ puts vtbls in the data segment by default; Microsoft C++ treats them as does Digital Mars C++.

-o[-+flag] run optimizer with flag
-o- No optimization (default)
-o Optimize for program speed
-o+space Optimize for program size
-o SPP only: send result to stdout
-ofilename Specify output filename
This specifies the name of the object [.obj] file if the -c switch is used, otherwise it specifies the output executable [.exe] file name. The dot extension is optional.
-p turn off autoprototyping
-p- turn on autoprototyping (default)

Autoprototyping is a Digital Mars C feature where if a function call is made and there is no prototype for the function, the compiler will create a prototype for that function based on the number and types of the arguments to it. Subsequent calls to that function will be checked against that prototype.

This obviously can cause trouble if functions that accept a variable number of arguments (like printf()) are called without a prototype for that function in scope.

Autoprototyping is irrelevant in C++ or if -r is used, because prototypes are then required.

-P Default to pascal linkage

Makes Pascal the default linkage for all functions and global data, instead of cdecl. Since all C library routines have cdecl linkage, they must be prototyped as such before being called. The main function must also be declared to have cdecl linkage or the linker cannot find it. For more information on declaring code to have alternative linkage, see Mixing Languages.

Using Pascal as the default linkage type results in about a 3% code size reduction and corresponding speed increase in generated code.

-P- Default to cdecl linkage
-Pz Default to stdcall linkage
-r strict prototyping
-r- turn off -r (default)
Enforces strict prototyping (all functions must be declared and prototyped before use). Standard library functions must include the appropriate header files. This behavior is the default for the C++ compiler and is highly recommended for C code, since it helps eliminate errors caused by type mismatches.
-R put switch tables in code segment

Switch tables are normally placed in the data segment (DGROUP). Sometimes, DGROUP space can be very limited, so the -R switch can be used to place switch tables into the code segment. Generated code will be slightly bigger and slower for switch statements with -R.

-R is ignored for 32 bit programs.

-s stack overflow checking

Inserts code into the function prologs to check for stack overflows. The resulting program generates an error message and aborts if it detects a stack overflow at run-time. This option is particularly useful for code with heavily recursive functions.

This switch is of interest mainly for 16 bit programs.

Note: The compiler does not support stack overflow checking for programs compiled with the DOSX (-mx) memory model.

-S always generate stack frame

Generates a stack frame for each function. -S is typically used when working with a symbolic debugger, but it can be specified by itself. The compiler always generates stack frames with either the -g or -gs option.

Without -S, the compiler does not generate a stack frame for functions with no local variables and no arguments.

-u suppress predefined macros
-v[0|1|2] verbose compile

-v0 Do not display any messages.

-v1 Default


-v2 Displays source and header file names, classes, and functions while they are being compiled. Displays total compilation time.

-w[-|n|x] warning messages
-w suppress all warning messages
-wn suppress warning message n
See Warnings and associated warning numbers for messages.
-w- enable all warning messages (default)
-wc warn on C style casts
This makes it easy to find and upgrade all the C style casts in C++ code to C++ style casts.
-wx treat warnings as errors
Warning messages tend to quickly scroll off the screen and go unnoticed, especially during building projects with lots of source files. -wx will treat warnings as errors, so they cannot be accidentally overlooked.
-W{0123ADadefmrstuvwx-+} Windows prolog/epilog
1: Full 2: Reduced 3: Smart callback A: EXE D: DLL
See Windows Prolog/Epilog Code Generation.
-x turn off compilation error maximum
Since many reported errors in a source file tend to be cascaded from the first error, the compiler normally aborts compiling a file after a certain number of errors are reported. Using -x will cause the compiler to proceed and try to compile the rest of the file.
-XD instantiate template for any functions declared but not defined
-XD- turn off -XD (default)

Consider the following:

template<T> int func(T) { return T; }
int func(double);

By default, since the specific declaration of func(double) exists, the compiler will not generate an instance of the template func(double), even if func(double) is called later in the source file. The programmer must provide an explicit definition of func(double) with a body at some point in the source code to the program.

If -XD is specified, the two lines above tell the compiler to generate an instance of func(double) from the template of func(T) as long as no explicit function body for func(double) appears in that same source file.

With -XD, the generated instance is placed into a COMDAT record, which means that if an explicit body is provided in another source file, that explicit definition will override the generated COMDAT definition. If the source file with the explicit body is compiled with -Nc (generate COMDATs for functions), then a linker error will result because there will be two different definitions for func(double).

-XD is the way the Digital Mars compiler versions previous to 7.0 worked by default, and is so provided for compatibility with previous versions.

-XIspec Create instance of template

Generate specific instances of templates that appear in the source file being compiled. For example, suppose the file test1.cpp contains the function template:

template<class T> T min(T a, T b) {
    return a < b ? a : b;

To create two instances of min() from test1.cpp (one for integers and one for doubles), use this command line:

dmc -c -XImin(int, int) -XImin(double, double) test1

Similarly, suppose stack.h contains this class template:

template<class T> class stack {
  T* top;
  T* bottom;
  int size;
  stack(int s) { top = bottom = new T[size = s]; }
  ~stack() { delete[size] bottom; }

  void push(T a) { *top++ = a; }
  T pop() { return *--top; }
  int size() const;

and test2.cpp contains this template:

#include <stack.h>
template<class T> int stack<T>::size() const
    return top - bottom;

To create a class for a stack of float types, use this command line:

dmc -c "-XIstack<float>" test2

Enclose this instance of the -XI option in quotation marks, since it contains the characters < and >. Without the quotation marks, the operating system would interpret the less-than (<) and greater-than (>) signs as file-redirection commands.

-XN no template function instantiation
Do not automatically expand any template function bodies.
=nnnn set stack size for compiler passes (obsolete)
-[0|2|3|4|5|6] 88/286/386/486/P5/Pro code

Select CPU instruction type.

-0 Generate code for 8088 and later CPUs
-2 Generate code for 286 and later CPUs
-3 Generate code for 386, 486, Pentium and Pentium Pro, and select instruction sequences that favor the 386
-4 Generate code for 386, 486, Pentium and Pentium Pro, and select instruction sequences that favor the 486
-5 Generate code for 386, 486, Pentium and Pentium Pro, and select instruction sequences that favor the Pentium
-6 Generate code for 386, 486, Pentium and Pentium Pro, and select instruction sequences that favor the Pentium Pro

This chart shows which CPUs each switch is compatible with:

CPU -0 -2 -3 -4 -5 -6
8088 Y N N N N N
286 Y Y N N N N
386 Y Y Y Y Y Y
486 Y Y Y Y Y Y
Pentium Y Y Y Y Y Y
Pro Y Y Y Y Y Y

Selecting a CPU type does not affect the memory model chosen, but -0 and -2 are invalid for 32 bit memory models. Since running Windows programs on an 8088 or a 286 is completely impractical, use -3, -4 or -5 even when generating 16 bit Windows code.

-6 is the default for 32 bit memory models.

The compiler supports the MMX instruction set in the inline assembler. MMX support is not affected by the CPU instruction type selection.

When using -3 or higher for 16 bit programs, beware of crash bugs resulting from conflicts with DOS terminate-and-stay-resident programs (TSRs) that do not save or restore the high-order 16 bits of the 32-bit registers.

Home | Runtime Library | IDDE Reference | STL | Search | Download | Forums