|
Compiling Compiling Code C Implementation C++ Implementation Language Extensions Mixing Languages Assembly Language Inline Assembler Optimizing Code Numerics Programming Regular Expressions Acrtused Pragmas Precompiled Headers Predefined Macros Warning Messages Error Messages Runtime Messages Linking Optlink Switches Module Definition Files Operation and Design Error Messages Win32 Programming Win32 Programming DOS and Win16 Programming Memory Models 16 Bit Pointer Types and Type Modifiers Handle Pointers DOS DOS 32 (DOSX) Win16 Win16 DLLs Win16 Prolog/Epilog C/C++ Extensions Contract Programming __debug statement __debug declaration Dynamic Profiling Embedding C in HTML Tools BCC CHMOD CL COFF2OMF COFFIMPLIB DMC DIFF DIFFDIR DUMP DUMPOBJ DUMPEXE EXE2BIN FLPYIMG GREP HC IMPLIB LIB LIBUNRES MAKE MAKEDEP ME OBJ2ASM PATCHOBJ RC RCC SC SHELL SMAKE TOUCH UNMANGLE WHEREIS Porting to DMC++ Switching to DMC++ from Microsoft from Borland Porting Guide |
Compiling CodeThis chapter describes how the compiler works by default and how to customize the compiler's output. It covers both 16-bit and 32-bit compilations.
The Command LineThe compiler comes in two forms, the command line tools and the IDDE. The free downloadable version is run from the command line. The IDDE version comes on the CD. To run the command line tools, open a console window. Under Windows XP, click on [Start] then [Command Prompt].A Simple ExampleTo illustrate compiling the classic hello world! program using the console compiler, create a text file hello.c with the contents:#include <stdio.h>
void main()
{
printf("hello world!\n");
}
Compile and link it with the following command:
dmc hellowhich will compile hello.c to create the object file hello.obj which is linked to generate the executable hello.exe. To run the executable type: hellowhich will print: hello world! Compilation ProcessDigital Mars C++ is an extremely fast one-pass compilation system with highly effective register utilization. An optional global optimization facility provides tight and efficient object code. Run the compiler from within the IDDE or more traditionally using dmc from the console command line.The compiler executables can compile either C or C++ files. The preprocessor is integrated in; but for specialized applications a separate standalone preprocessor is also included. As it runs, the compiler reads the source files, executes all preprocessor functions, checks for any syntax errors, optimizes the program, generates machine code, and outputs an object (.obj) file suitable for input to the linker. Startup codePrograms compiled with Digital Mars C++ call one of several startup functions before passing control to a program's main() routine. (The startup function called depends on what kind of application is being built, as described in __acrtused.) This startup function performs any required initializations such as initializing data and running the static constructors.
There are several files that contain startup functions (all with
different names) in several subdirectories of the Digital Mars
\dm\src directory.
Specifying compiler outputBy default, Digital Mars C++ compiles and links the source files given on the command line and generates an executable file whose name is the same as the name of the first source file with the extension replaced with .exe. To generate different files or additional files use the dmc options described below or via corresponding options in the Compiler Output subpage on the Build page of the IDDE's Project Settings dialog box.
-e Show preprocessor output -EC Leave comments in preprocessed output -EL Do not emit #line directives -l[listfile] Generate source listing file -ofilename Specify output .obj or .exe filename -v[0|1|2] verbose compile
Support for C language features
-J Treat chars as unsigned -Jm Relax type-checking -Ju char and unsigned char are the same type (unsigned char) -p Turn off function auto-prototyping -r Require strict function prototyping -u Suppress non-ANSI predefined macros
Support for C++ language featuresDigital Mars C++ supports run time type identification, exception handling. These C++ language features are not enabled by default; to enable them, specify compiler options as described below.
-Ar Enable run time type identification -Ae Enable exception handling -cpp Compile all source files as C++ -J Treat chars as unsigned -u Suppress non-ANSI predefined macros
Suppressing warnings and errorsBy default, the compiler generates warnings about certain constructs that, while legal, are likely mistakes. Warnings can be disabled individually or as a group. Warnings can also be treated as errors. In the IDDE, these are set via the Compiler Output subpage on the Build page of the IDDE's Project Settings dialog box. See "Warnings and associated warning numbers" for messages.
-w[number] Suppressing warning message number -w- Show all compiler warnings -wx Treat warnings as errors -x Turn off compilation error limit
Dynamic profiling
Choosing a memory modelWhen programming for Win32, it is not necessary to choose a memory model. The compiler defaults to compiling for Win32. Compiling 16 bit code or DOS extender code will require choosing a memory model.Memory model choices trade off between meeting minimum system requirements, maximizing code efficiency, and accessing as much available memory as possible. For more information, see Chapter 7, "Choosing a Memory Model." To specify the memory model, use the dmc options described below or use the Memory Models subpage on the Build page of the IDDE's Project Settings dialog box. For more information on memory allocation, see Chapter 5, "Using Assembly Language Functions."
Note: For Win32, it is imperative that SS==DS==ES at all times. Otherwise the Win32 API functions will crash. (CS need not be equal to SS, FS is reserved for thread-related information, and GS is available for general use.) Thus, SS==DS==ES for the Win32 (-mn) memory model. Here are some example combinations of memory model specifiers: -ms Small model with SS == DS -msw Small model SS != DS -mc Compact model -mt .com file -mluw Large model, SS != DS, Reload DS The program stackWin32 programs generally do not need to worry about stack overflows, but other memory model options require some attention to it.In all memory models, the stack grows downward toward statically allocated data. If the stack grows larger than its allocated size, statically allocated data are destroyed, and the program performs unpredictably. To check if the stack grows past the allocated limit, use the special function called _chkstack. Call _chkstack from functions that potentially use large amounts of stack space, such as recursive functions. If the stack exceeds the allocated size, _chkstack aborts the program with the message: Stack overflowUse the -s compiler option (see below) to generate stack-overflow checking code on entry to every function, although this increases program size and reduces speed. Use stack-overflow checking if you suspect stack-overflow errors (a symptom is a mysterious crash). Controlling stack size for DOS programsControl a DOS program's stack size in the following ways:
For a DOS program, do not use the linker /STACK parameter to set the stack size; use one of the methods described above. The default stack size is 8192 bytes for 16-bit compilations and 16KB for 32-bit compilations.
Aligning data objectsIn 16-bit compilations, the compiler align data objects on 16-bit word boundaries. This improves the execution speed of code running on CPUs with a 16-bit data bus (like the 80286). The default alignment for 32-bit compilations is on 32-bit boundaries. The default alignment of structure members depends on the memory model used for the compilation. Change the alignment within structures via the -a compiler option (see the section "-a Specify structure alignment" later in this chapter), so that structure members are aligned on different boundaries. This option is useful for defining a struct that maps onto a hardware device or a predefined data element.You can control alignment only within structures; the compiler still aligns all other data objects on word or dword boundaries. Struct member alignment can also be specified with the #pragma pack preprocessor directive. Refer to Chapter 3, "Digital Mars C++ Language Implementation" for more information. The C++ compiler does not generate structs with a size of 0 bytes if there are no nonstatic data members; the minimum size of a struct is 1 byte. This prevents new() from returning 0 when it tries to allocate an instance of a struct. Warning: Each file referencing a structure must be compiled with the same type of alignment. If two files compiled with different alignment reference the same structure, any erroneous results could be hard to debug.
Compiling for debuggingPrograms compiled with Digital Mars C and C++ can be debugged using many third-party debuggers, as well as the Digital Mars C and C++ debuggers.There are two basic types of debugger that can be used with Digital Mars C and C++ programs: fully symbolic debuggers (those that work with symbolic information, like the Digital Mars debuggers or Microsoft Corporation's CodeView), and partially symbolic debuggers (those that require only source code line numbers and map file information, such as Microsoft's Symdeb).
Compatibility with third-party C debuggersFully symbolic debuggers that are compatible with the data format used by Microsoft CodeView should give acceptable results when used to debug C programs compiled with Digital Mars C++, provided they can handle both C and Pascal function calling conventions. Some information on local variables may not be available due to the automatic register assignments carried out by Digital Mars compilers. (Digital Mars C and C++ make intelligent use of registers within functions, automatically assigning frequently used variables to registers. This register assignment uses any available register and not simply SI and DI.) Some debuggers cannot handle variables in registers other than SI and DI and consequently cannot display or track them.The Digital Mars C and C++ debuggers can display, modify, and track all the local variables within a function. Compatibility with third-party C++ debuggersAlthough some other third-party C debuggers can partially debug C++ programs, they cannot obtain or handle all the information needed to fully debug C++ code. The main difficulties are these:
Overview of compiler debugging optionsIf the compiler always generates full debugging information for all variables, then the object files would be very large, and the linker would have to remove a great deal of redundant information. You can control the level of debugging information the compiler provides with the -g option (see the section "-g Generate debugging information" later in this chapter). The compiler can produce five levels of debugging information:
Debugging options
-g Generate debug info for types of referenced variables -g4 Generate Codeview 4 format debug info. This is the default. -gf Generate debug info for full class hierarchy for any referenced classes. -gg Make static functions global -gh Generate debug info for all global structs and typedefs -gl Generate line number info only -gp Generate pointer validation code -gs Generate symbol info only (do not generate line number info) -gt Generate prolog/epilog for use with the dynamic profiler. -S Always generate stack frame
Linking for debuggingWhen compiling for debugging, the compiler automatically passes the correct information to the linker. If you use a separate link step, you need to pass the appropriate options to the linker yourself.These are the options for Digital Mars OPTLINK or Microsoft LINK for all levels of debugging information:
See the User's Guide and Reference for more information on using the Digital Mars debuggers. Notes on debugging with CodeViewUnlike the Digital Mars C++ debugger, which is statement oriented, the Microsoft CodeView debugger is a line oriented source debugger. At the source code level, the smallest unit of code CodeView can handle is a line, not a statement. To use CodeView most effectively with Digital Mars C++, follow these rules:
Debugging aids in the run-time libraryThere are a number of features in the run-time library that help detect common run-time errors:
Specifying linker and assembler optionsThe compiler options described below let you run third party linkers and assemblers on the SC command line, or pass options to the linker or assembler.
-Llinker Use linker linker instead of OPTLINK. -L/switch Pass /switch to linker. -Masm Use assembler asm instead of MASM. -M/switch Pass /switch to assembler.
Controlling segmentationWhen writing large 16 bit Windows programs, you sometimes need to place functions that frequently call each other into the same segment. This optimization helps speed execution. This section explains how to segment your code. Use these methods independently or in any combination.
Preventing data segment overflowMany large programs run out of space in the default data segment DGROUP. The solution is to move some data out of DGROUP into other segments. Here are some methods you can use:
Data declared as far should be data that is relatively large and is accessed relatively infrequently, as more overhead is required to access those data. If another module should reference far static data, declare it as far, as in: extern int __far array[];Otherwise, the compiler assumes that the data is in the default data segment DGROUP. Digital Mars C++ differs from some other compilers in this respect— extern data is not assumed to be in DGROUP. Although our implementation involves more work on the program- mer's part (putting __far in the right places), the control this offers makes it very worthwhile for high-performance applications. Also, most applications need less than 64KB of static data, and so need not pay a penalty for assuming that extern data is not accessible via DS. Virtual function tables (vtbls)The compiler generates a table of pointers to functions for each class that has virtual functions or is derived from a class with virtual functions. In the small data models (Tiny, Small, and Medium), it creates these tables in DGROUP by default. For the Compact and Large data models, it writes these tables to the code segment by default.To further minimize use of code space in Compact and Large model programs, place vtbls in far data segments with -NV. Segmentation optionsUse the options described below to control how the compiler segments your program.
-Ns Put strings in expressions into code segment -NTname Set code segment name to name. -NV Put virtual function tables in far data segments. -R Put switch tables in code segment -GTnnnn Put large arrays in far data segments.
Code generation optionsThe options described below control how the compiler generates code.
-c Compile only, do not link executable. -C Disable inline function expansion. -D[macro[=text]] Define macro -Nc Perform function level linking -NF ignore extended keywords -NL Do not embed default library record -o Optimize code for speed -o+space Optimize code for space -P Default to pascal linkage
Compiling for WindowsSee Windows Prolog/Epilog Code Generation.Templates
-XD instantiate template for any functions declared but not defined -XN no template function instantiation
Internationalization Options
|