Last update Jul 24, 2002
sc { { @responsefile } { file } { switches } }where the { } means "repeated 0 or more times". SC with no arguments prints a short help file to stdout.
;Comments are lines where the first non-blank character ; is a ';' [Environment] INCLUDE=c:\dm\bin LIB=c:\dm\lib CFLAGS=-v -w ;Note that %PATH% gets replaced by the previous value of ; the environment variable PATH. PATH=c:\dm\bin;%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):
[Environment] INCLUDE=%@P%..\BIN LIB=%@P%..\LIB CFLAGS=-v -w PATH=%@P%..\BIN;%PATH%which makes the settings in sc.ini independent of where the SC 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 SC 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. If you wish, for example, to use sc.ini to append an INCLUDE path to the existing INCLUDE path, it can be written as:
[Environment] INCLUDE=%INCLUDE%;c:\dm\include
.c .cpp .cxx .cc .c++ .asm .s .rcThe extension of the file determines what is done with the file.
no extension any other extension .c Run C compiler .cpp .cxx .cc .c++ Run C++ compiler .asm .s Run assembler .lib .a Include file as a library to the linker .obj .o Include file as an object file to the linker .exe .com .sys .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
Alignment can also be controlled within a source file by using #pragma pack().
Effects on C and C++:
Effects on C:
Effects on C++:
char abc[4] = "1234";
where there is no room for the trailing 0 is invalid.
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).
For link compatibility with Microsoft C++ compiled DLLs, but still using RTTI, compile with -ER:
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.
#undef strcmp /* use runtime library version of strcmp */
file.obj : $(file.dep) file.c sc -c file -d
#define macro "this is a string"
Win32 implementations have an emulator for the numeric coprocessor, so -f is the default for the -mn memory model.
No Pentium Pro or Pentium MMX chips have this bug.
-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.
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 you need 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 if you're curious as to what the compiler is doing.
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:
__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.
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 functionsYou must provide the code for these functions; 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.
-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. -GTnnnn Allocate arrays and structs larger than nnnn to far data segments. -GT 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 you use -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). -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. -HMaddress 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. -HS only search -Ipath directories Directs the compiler to search for #included header files only along the path specified by the -I compiler option. 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 \. You can also specify multiple paths. For example: Sample option 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: -j0 Japanese, prefix bytes are 0x81..0x9F and 0xE0..0xFC -j1 Taiwanese and Chinese, prefix bytes are 0x81..0xFC -j2 Korean, prefix bytes are 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; or: unsigned char c; int i = c; or: 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 linkers have 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 SC 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: sc 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 SC 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). If you are compiling 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). -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: o Compiling code that will go into a library, getting rid of all those records can result in a substantial reduction in library size. o Compiling code that will be linked with code generated by other compilers. -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 you cannot write into strings placed in the code segment. If you need to write into a string, and wish to 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 Chapter 4, "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. You typically use -S when working with a symbolic debugger, but you can also specify it by itself. The compiler always generates stack frames if you specify 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 -v -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: sc -c -XImin(int, int) -XImin(double, double) test1 Similarly, suppose stack.h contains this class template: template< class T> class stack { private: T* top; T* bottom; int size; public: 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: sc -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: -0 -2 -3 -4 -5 -6 +----------------- 8088 | Y 286 | Y Y 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.
Copyright © 1995-2001 Digital Mars. All Rights Reserved.