Porting Guide
This chapter lists and describes compiler and/or linker errors and other problems that can occur when porting existing code to Digital Mars C++.What's in This Chapter
- General porting issues.
- Porting issues pertaining to code written with Microsoft Visual C++.
- Porting issues pertaining to code written with Borland C++ Version 3.
- Porting issues pertaining to older Zortech C++ code, or code written with previous versions of Digital Mars C++.
- Issues pertaining to porting 16-bit Windows 3.1 code to Windows 95 or Windows NT.
General tips on porting to Digital Mars C++
This section provides tips on how to solve problems that might occur when porting code to Digital Mars C++ that was written with another compiler, or with a previous release of Digital Mars C++ or Zortech C++. For related information, see Switching to Digital Mars C++.Problem: iostreams library incompatible with -Ju
The Digital Mars C++ Version 7 iostreams library is incompatible with code compiled with the -Ju compiler option; syntax errors and link errors result. This is because, when you specify -Ju, the compiler treats char and unsigned charas the same type. This can cause distinct functions to appear to be the same, and can make mangled names different from the corresponding names in the iostreams library.Here are two recommended solutions:
- Do not compile code that includes iostreams headers with the -Ju compiler option.
- Replace all unsigned char and BYTE types with char, and compile with the -J option. (This solution is more compatible with Microsoft C++.)
Problem: Linker error "EXE header > 64k"
This error results if your code exports too many names. If names in a DLL are not referenced by name at run-time using the Windows API function GetProcAddress(), you can specify the /BYORDINAL and /NONAMES linker options, which remove all names from the DLL header and use the corresponding ordinal numbers instead.Problem: GetProcAddress() fails
If you are exporting names by ordinal value (see above), no names are included in a DLL, and a call to GetProcAddress() with the name of the procedure will fail. This can also result in problems at link time and load time. Here are two recommended solutions:- Link with the linker option /XUPPER.
- Define an ordinal number for each name in the definition (. DEF) file, and call GetProcAddress() with the ordinal number instead of the procedure name.
Problem: Unsupported build steps
Your .MAK or .BAT files may contain build steps that the Digital Mars C++ IDDE does not support. For example, a makefile might call an SQL preprocessor that emits C code. The SQL code would need to be processed before the IDDE compiles the C files. You can solve this problem by adding a .MAK file to the Digital Mars C++ project. Put it before the compile step in the IDDE's Build Order list box. Then make a target "clean" (which should not be the first target); "clean" will be built when you rebuild the entire project. Note that the first target will be built in the makefile directory; "clean" will be built in the project directory.Problem: Linker error "DGROUP + Stack + Heap exceeds 64k-16"
The data segment of a 16-bit program can only be 64K bytes long. The combined data definitions of all your modules has exceeded this threshold. To solve this problem, check the "Set Data Threshold" check box on the Code Generation subpage of the Build page in the IDDE's Project Settings dialog box (or use the -GT1 compiler option). This directs the compiler to place data objects larger than the specified size in their own far data segments. Setting the size to 1 puts all data objects in individual data segments.Problem: Moving a project "loses" the libraries
In this case, the compiler cannot find libraries after you move an existing IDDE project to a new directory. When you add a library in the \dmc\lib directory to a project, do not specify a path. This prevents the IDDE from assigning the library a path that is relative to the project directory.Problem: Path problems in sc.ini
If you specify the include path for your project in sc.ini, non-Digital Mars tools that rely on the definition of the INCLUDE environment variable for path information cannot access the information. Use autoexec.bat, the Windows NT Registry, or the project include directory setting instead.Problem: Path problems in autoexec.bat
If you specify the include path for your project in autoexec. bat, you need to restart Windows in order to change it, and the information will not be used for Windows NT builds. Use sc.ini, the Windows NT Registry, or the project include directory setting instead.Problem: Path problems with project include directory setting
If you specify the include path for your project in the IDDE's "Project include directory" setting, non-Digital Mars tools cannot access the information, and it will be specific to that project only. Use autoexec.bat, the Windows NT Registry, or sc.ini instead.Problem: Path problems in NT Registry
If you specify the include path for your project in the Windows NT Registry, you won't be able to change it via a batch file, and it won't be available for Windows 3.1 builds. Use autoexec.bat, the project include directory setting, or sc.ini instead.Problem: 16-bit programs with virtual functions crash
In this case, programs that use classes that define virtual functions cause General Protection Faults. For example, an executable defines a class with virtual functions, and the virtual functions are called by DLLs. This happens because executables with virtual functions must have "smart callbacks" set; otherwise, the function will be invoked with the wrong value for DS. (In the IDDE, click the "Load DS from SS" button in the Windows Prolog/ Epilog subpage of the Build page of the Project Settings dialog box.) For more information, see Win16 Programming Guidelines.Problem: You need generic .MAK files
To create generic makefiles that can be called from different projects, get the name of the calling project from the predefined identifier MASTERPROJ.Problem: You need to link with a DLL at link time only
To link an EXE or DLL with another DLL at link time only:- For the called DLL, set Export By Ordinal, Don't ExportNames, and Generate Import Library in the Linker subpage of the Build page of the Project Settings dialog box.
- For the calling EXE or DLL, add the resulting .LIB file to the project.
Problem: You need to link with a DLL at run-time only
To link an EXE or DLL with another DLL at run-time only:- For the called DLL, turn off Export By Ordinal, Don't Export Names, and Generate Import Library in the Linker subpage of the Build page of the Project Settings dialog box.
- For the calling executable or DLL, call MakeProcInstance() with the name of the function.
Tips on porting from Microsoft Visual C++
This section provides tips on how to solve problems that might occur when porting code to Digital Mars C++ from Microsoft Visual C++. For related information, see Converting from Microsoft.Problem: _ExportedStub missing
The Microsoft C++ libraries provides the entry point _ExportStub, which can be exported by user .DEF files. Remove _ExportStub from your .DEF files; it is specific to Microsoft's implementation of its internal routine _GetGROUP. This change is unlikely to introduce any problems.Problem: WIN32 and _X86_ not defined
32-bit versions of Microsoft C++ provide a .MAK file that defines -DWIN32= 1 and -D_ X86_= 1. Digital Mars C++ does not provide this file. Digital Mars C++ defines these macros in the header file SCDEFS.H, which is included whenever you include a Win32 API header file. If you are not using the Win32 API, you can explicitly include SCDEFS.H, or define WIN32 and _X86_ on the compiler command line or with the IDDE.Problem: overloaded functions produce errors
Microsoft C++ (and Borland C++) do not distinguish between overloading of int and unsigned short. Digital Mars C++ does, and generates an error for each ambiguous reference. For example:void f(unsigned short); void f(int); void main () { short s; f(s); }In Digital Mars C++, s can be promoted to either int or unsigned short, whereas Microsoft C++ always calls f(int). Problems in user code can be due to one function being declared in two slightly different ways, so that it looks like two different functions to Digital Mars C++. For example:
void f(WORD); // Later on in different #include'd file void f(int); // Looks like different C++ function
Problem: _MT not automatically defined
32-bit Microsoft C++ sets _MT=1 if the /MT (multi-threaded) option is specified. If /MD (multi-threaded DLL) is specified, 32-bit Microsoft C++ sets _MT=1 and _DLL=1. Digital Mars C++ has no equivalent switches because its 32-bit run-time library is always multi-threaded. To solve this problem, define _MT and _DLL on the dmc command line as necessary.Tips on Porting from Borland C++
This section provides tips on how to solve problems that might occur when porting code to Digital Mars C++ from Borland C++ Version 3. For related information, see Converting from Borland.Problem: _DEFS.H
Borland C++ provides a file BC\ INCLUDE\_ DEFS.H, which their STDIO.H library includes. This file contains a number of definitions used in Borland header files; these definitions might also appear in user code. Although Digital Mars C++ does not provide equivalent definitions, you can explicitly include Borland's _DEFS.H in your Digital Mars C++ compilation. This is unlikely to introduce any problems.Problem: const * to non-const * conversion
Borland C++ permits implicit conversions between const * types and non-const * types. Digital Mars C++ does not permit this. For example:const char *p; char *q; q = p; // causes "cannot implicitly convert" // error in DMC++Add explicit casts as necessary to add or remove const-ness An easy way to eliminate const-ness problems is to add this code:
#define const
Problem: signed * to unsigned * conversion
Borland C++ permits implicit conversions between signed * types and unsigned * types. Digital Mars C++ does not permit this. For example:unsigned int *p; int *q; q = p; // causes "cannot implicitly convert" // error in DMC++Add explicit casts as necessary to add or remove signed-ness.
Problem: int to pointer conversion causes errors
Borland C++ allows ints to be converted to pointers with only a warning. This is an error in Digital Mars C++. To fix this error, explicitly cast or convert ints to pointers as appropriate.Problem: overloaded functions produce errors
Borland C++ (and Microsoft C++) do not distinguish between overloading of int and unsigned short. Digital Mars C++ does, and it generates an error for each ambiguous reference. For example:void f(unsigned short); void f(int); void main() { short s; f(s); }In Digital Mars C++, s can be promoted to either int or unsigned short, whereas Borland C++ always calls f(int).
Problems in user code can be due to one function being declared in two slightly different ways, so that it looks like two different functions to Digital Mars C++. For example:
void f(WORD); // Later on in a different #include file... void f(int); // Looks like a different C++ function
Problem: const-ness of overridden functions
Borland C++ allows a function of a derived class to have different const-ness from the same function in the base class, in violation of ARM 10.2. For example:class A {virtual int f(void);}; class B: public A { const int f(void); // DMC++ generates "name previously declared // as something else" error };To solve this problem, rewrite your code to make the const-ness of functions in derived classes match that of their base class equivalents.
Problem: Definition of max and min macros for C++
The Borland C++ windows.h header file does not define the macros max and min for C++. The Digital Mars C++ version of windows.h defines these macros.Here are two recommended solutions:
- To keep min and max from being defined, add this code
before including windows.h:
#define NOMINMAX.
- Add NOMINMAX to your project's Defines list box in the IDDE (choose Project -Settings, click the Build tab, and choose Compiler).
Problem: Inclusion of windows.h in resource files
The Borland IDE implicitly includes windows.h in any .RC file it compiles. The Digital Mars IDDE does not. Therefore, you need to explicitly add the code #include <windows.h> to .RC files.Problem: Redefinition of default arguments
Borland C++ allows redefinition of default arguments (in violation of ARM 8.2.6). For example:int f(int i = 0); int f(int i = 0); // DMC++ gives errorRemove the second default definition. For example:
int f (int i = 0); int f (int i);
Problem: Automatic enum conversions
Borland C++ provides an option to "treat enums as ints." Digital Mars C++ does not allow implicit conversions of ints to enums, or implicit conversion of enums to other enums in C++ compilations. For example:enum color (black, red, green, blue); enum color current_color = NULL; // DMC++ errorThere are two recommended solutions:
- Change the code to use equivalent values from the enum
in question. For example:
enum color (black, red, green, blue); enum color current_color = red;
- Cast int values to the enum. For example:
enum colorcurrent_color = (enum color) NULL;
Problem: Undefined escape cequences
Borland C++ ignores undefined escape sequences in strings. For example, it interprets \U as U. Digital Mars C++ generates an error in this case. To avoid the error, remove unnecessary escape characters (\) from strings.Problem: Return types for constructors/destructors
Borland C++ allows a return type for constructors and destructors (in violation of ARM 12.1 and ARM 12.4). Digital Mars C++ does not allow this. For example:void A::A() {...} // DMC++ generates "illegal constructor // declaration" errorRemove the return type from the declaration. For example:
A::A() {...}
Problem: Differentiating functions by addressing or calling conventions
Borland C++ differentiates between two functions with the same name in a class if they have different addressing or calling conventions. Digital Mars C++ does not. For example:class x { void func(); void __far__ pascal func (); // DMC++ generates "function is already // defined" error };The problematic declaration is most likely a mistake; remove the additional declaration.
Problem: No implicit function declarations for derived classes
Borland C++ allows functions to be defined for a derived class that were only declared for the base class, not the derived class. For example:class A { public: virtual void f() = 0; }; class B: public A {}; void B::f() // DMC++ generates "function is // not a member of class" error {...}Put explicit declarations for all of a class's functions in the class declaration. For example:
class B: public A { public: void f(); };
Problem: findfirst() and findnext()
The Borland versions of the functions findfirst() and findnext() take different parameters from their Digital Mars counterparts. Rewrite your code to use the Digital Mars versions of findfirst() and findnext(), or use _dos_findfirst() and _dos_findnext(). For information see the Digital Mars C++ Runtime Library Reference.Problem: _control87() parameters
Borland C defines various constants for use as parameters to the _control87() function (MCW_EM, EM_INVALID, EM_DENORMAL, and so on), whose names differ from their Digital Mars equivalents. You can form the equivalent Digital Mars C constants by adding an underscore (_) to the Borland version; for example: _MCW_EM or _EM_INVALID.Problem: __DLL__ macro defined for DLL compilations
Borland C defines the macro __DLL__ for DLL compilations; Digital Mars C does not. Here are two recommended solutions:- If you are using the dmc command line compiler, add -D __DLL__ to the command line for all DLL compilations.
- From the IDDE, add __DLL__ to your project's Defines list box in the IDDE (choose Project-Settings, click the Build tab, and choose Compiler).
Problem: undefined type dosdate_t
The type dosdate_t declared in Borland C's dos.h file is not defined in Digital Mars C. Change all instances of dosdate_t to _dosdate_t.Problem: no values.h file
Borland C provides a file values.h, which defines various implementation defined limits (for instance, MAXINT, which represents the largest int). Digital Mars C does not provide an equivalent file. You can use the ANSI standard file limits.h instead. To do this, you will need to change the names of most of the defined identifiers (MAXINT is called INT_MAX, for instance).Problem: Typos in long identifiers
Borland C uses the first 32 characters in identifiers; Digital Mars C uses the first 254. This can expose typing errors at the ends of long identifiers. For example:#define I_am_not_very_happy_monday_morning 1 i = I_am_not_very_happy_monday_mornings; // BC does not generate an error; dmc doesFix any typing errors as needed.
Problem: _argc and _argv not declared
Borland C declares the variables _argc and _argv in dos.h. Digital Mars C++ does not. Add the following declarations as needed:extern int __cdecl _argc; extern char ** __cdecl _argv;Note that these names are not part of the published Digital Mars C/C++ run-time library interface, and are subject to change.
Problem: Invalid bitmap syntax
The resource compiler run from the Borland IDE accepts an alternate syntax for BITMAPs, where the actual bitmap is specified in the code rather than in a file. For example:Example BITMAP BEGIN '42 4D 5E 00 ...Digital Mars's rcc and Microsoft's rc do not accept this syntax. Use Borland's Resource Workshop to convert the text to a .BMP file and change the code to:
Example BITMAP.BMP
Problem: Invalid pointer conversions
Borland C allows conversion of different pointer types with only a warning. Digital Mars C++ does not. For example:void f() { int *p; char **q; q = p; // dmc generates error "cannot implicitly convert"Examine your code for correctness, and add explicit casts where appropriate.
Problem: Names declared in different header files
Some names that are defined in both Digital Mars C++ and Borland C++ are declared in different header files. An example is the run-time library function coreleft(), which is declared in stdlib.h in Digital Mars C++ and alloc.h in Borland C++. To fix this problem, change the header files that your code includes as appropriate.Problem: Automatic definitions
Borland C allows an extern variable to be declared without ever being explicitly defined. In Digital Mars C++, this results in the error "symbol undefined:< symbol>" at link time. For example, where the following is a complete program:extern int a; void main() {a = 1;}Add explicit definitions to your code as required.
Problem: Names referenced in .ASM files
Borland C++ mangles only function names. Digital Mars C++ mangles both function and variable names. This can cause link errors on names referenced in .ASM files. For example: extrn _a: word produces a link error in DMC++ because the correct name is ?a@@3HA.There are two recommended solutions:
- Add extern "C" to declarations of names referenced
in .ASM files before they are defined. For example:
extern "C" short a; short a;
- Change the assembly language code to refer to the
Digital Mars C++ mangled names. For example:
extrn ?a@@3HA: word
Problem: Inconsistencies in declarations at link time
Borland C++ only mangles the names of variables slightly. For example, for function pointers it does not encode the parameters of the function; Digital Mars C++ does. This can expose inconsistencies in declarations at link time.Make declarations consistent where needed.
Problem: Inconsistencies in _pascal declarations at link time
Borland C++ does not encode the _pascal calling convention modifier into mangled names (except by making the mangling all lowercase); Digital Mars C++ does. This can expose inconsistencies in declarations at link time for case-insensitive links.Make declarations consistent where needed.
Problem: opendir, closedir, etc. not available
The Borland library functions opendir, closedir, readdir, and rewinddir functions are not available in Digital Mars C++.Rewrite your code to use _dos_findfirst, _dos_findnext, or findfirst/ findnext(). For information, see the Digital Mars C++ Run-time Library Reference.
Problem: Linker cannot export names
If the Digital Mars linker cannot find names listed in the project .DEF file's EXPORT list, one of these issues is the cause:- Digital Mars C++ and Borland C++ mangle C++ names differently (see the information on name mangling above). If this is the problem, you need to disassemble the object module(s) to see what the names should be in Digital Mars C++.
- Borland C++ does not mangle variable names (see "Problem: Inconsistencies in declarations at link time" above). If this is the problem, add extern "C" to the appropriate declarations as described above.
- The Borland linker does not complain about nonexistent names. If this is the problem, delete the nonexistent names.
Problem: Undefined Borland identifiers in .RC files
Some Borland predefined identifiers, like IDHELP, are undefined when you compile resources with Digital Mars's rcc.Borland's resource compiler automatically includes bwcc.h, so you need to explicitly include bwcc.h in the .RC file.
Problem: BC program does not load after conversion to dmc
If this is your problem, you might find that one or more DLLs do not load, or "undefined dynalink" errors occur.Make sure that all Digital Mars compiler options match their Borland equivalents. For example, exports can be uppercase, by ordinal, export all far, and so on.
Problem: BC program does not run after conversion to dmc
If a Borland program compiles but does not run, check that all Digital Mars compiler options match their Borland equivalents. For example, Borland's default struct alignment is on byte boundaries, Digital Mars's is on word boundaries.Problem: _new_handler is not declared
Borland C++ declares pvf _new_handler in the file new.h. Digital Mars C++ does not.Simply add the declaration _PNH _new_handler as needed.
Problem: _new_handler behavior is different
Borland's _new_handler function takes no arguments, and exits on failure. Digital Mars's _new_handler takes one argument (the number of bytes to make available) and returns zero on failure.Simply recode calls to _new_handler as needed.
Problem: "class huge" syntax not supported
Borland C++ allows the keyword huge after class in a class declaration. Digital Mars C++ does not. For example:class huge A;Rewrite any class declarations that use the huge keyword.
Problem: Non-Pascal names not found at DLL load time
Windows cannot find exported names in a DLL if they are lowercase. Borland's IMPLIB solves this problem by always exporting names in DLLs by ordinal. Digital Mars's linker does not automatically do this; therefore, some non _pascal names might not be found when a DLL is loaded.Link with these Digital Mars linker options: /XUPPER (Export, uppercase) and /BYORDINAL (Export by ordinal).
Problem: Can't convert between unsigned char and char
The Borland C++ option -K makes unsigned char and char the same type.Try one of these two possible solutions:
- Compile with the Digital Mars C++ compiler option -Ju, which is similar to Borland's -K option. Note, however, that -Ju is incompatible with Digital Mars's iostreams library (as described under "Problem: iostreams library incompatible with -Ju" above). Do not use -Ju to compile code that includes iostreams headers.
- Search for and replace all unsigned char and BYTE types with char, and compile with Digital Mars's -J compiler option. (This solution is more compatible with Microsoft C++.)
Tips on porting from previous Digital Mars releases
This section provides tips on how to solve problems that might occur when porting code from previous releases of Digital Mars C++ or Zortech C++. For related information, see Switching to Digital Mars C++.Problem: asm() function does not compile
Zortech C++ allowed instructions to be assembled from integers using the asm() pseudo-function. For example:asm (0x8C, 0x96, 0xCC, 0xFE);Digital Mars C++ does not provide this function. Therefore, you need to replace asm() calls with calls to __emit__. For more information, see Using Assembly Language Functions.
Problem: ios class not declared in iomanip.h
Previous versions of the iostreams library declared the ios class in iomanip.h. The current version of iostreams does not.You need to explicitly include iostream.h.
Problem: Zortech library names are different
Zortech C++ library names specified in makefiles are different from the corresponding Digital Mars C++ names (ZWL corresponds to SWL, for example).Change your makefiles to use the Digital Mars C++ library names. Note that, since the names of libraries are specified in object files, it may not be necessary to explicitly specify them in the makefile.
Problem: Compiler control program has a different name
The Zortech C++ compiler control program was ZTC.EXE. The Digital Mars C++ equivalent is dmc.Change makefiles, batch files, and so forth to run dmc instead of ZTC.
Problem: Missing #endifs generate errors
Zortech C++ allowed #endif directives at the end of files to be omitted; it interpreted End of File as any number of #endifs. Digital Mars C++ does not.Add #endif directives to the ends of files as appropriate.
Problem: __pascal names mangled in C++ files
Zortech C++ did not perform C++ name mangling on __pascal names. In Digital Mars C++, the __pascal modifier changes the calling sequence, but does not affect name mangling.Add the modifier extern "C" to declarations that should not be mangled. For more information, see Mixing Languages.
Problem: Jumps around variable initializations disallowed
Zortech C++ allowed jumps around variable initializations, in violation of ARM 6.4.2. Digital Mars C++ does not allow this. For example:switch (i) { int v1 = 2; // error case 1: int v2 = 3; case 2: if (v2 == 7) // error ...There are two recommended solutions for this problem:
- Move the variable initialization out of the case statement.
- Add braces around the declaration to restrict the variable's scope to be within the area that the flow of control can jump around.
Problem: Differences in mangled names
Zortech C++ code might not link with Digital Mars C++ because .ASM files reference mangled names. The Digital Mars C++ name mangling scheme differs from Zortech C++ name mangling.Use the obj2asm utility to obtain the new mangled names, and manually edit the assembly language files to use these names. For information on Digital Mars C++ name mangling, see Mixing Languages.
Problem: WEP in user code causes a link error
Digital Mars C++ Version 6 allowed users to specify a WEP function in a DLL. Digital Mars C++ Version 7 provides a WEP function in the library, which handles static destructors and other cleanup functions on exit from the DLL. Thus, WEP functions should not be used if these function are required.If a DLL requires special termination procedures, put them in a function called _WEP. Digital Mars's WEP automatically calls _WEP. An _WEP function is not required, however.
Problem: Access to protected members not allowed
Zortech C++ allowed access to protected member functions, in violation of ARM page 253. (Base class members can only be accessed through a derived class.) For example, the following is an error in Digital Mars C++:class A {protected: int x }; class B: public A { void f() { x = 10; } void f1() { A *p = new A; p-> x = 10; // error } friend void f2(A*); friend void f3(B*); }; void f2(A* a) { a->x = 10; } // error void f3(B* b) { b->x = 10; }To solve this problem, recode invalid constructs as necessary.
Problem: Mismatches in C++ const functions not allowed
Zortech C++ allowed mismatches in function declarations involving const-ness. For example, the following constructs, which were valid in Zortech C++, are invalid in Digital Mars C++:class A { public: int operator== (A&); }; class B { A a; int operator==(B& b) const { return (a == b.a); // error in DMC++ 7 } };In the above example, since B::operator== is const, B::a is const, but there is no matching function in A. To fix the error, you need to add the required matching function. To fix the example code above:
class A { public: int operator==(A&); int operator==(A&) const; };
Tips on porting Win16 Code to Win32
This section provides tips on how to solve problems that might occur when porting 16-bit Windows 3.1 code to a 32-bit Windows environment. See Win32 Programming Guidelines, for general information on porting 16-bit code to Win32.Problem: Files not found when porting to Windows NT
Symptoms of this problem include .MAK or .BAT files generating errors, or programs not finding files.Windows NT does not run the autoexec.bat file, so your PATH environment variable (and other environment variables) may not be set. You need to manually add these values to the Windows NT Registry.
Problem: 32-bit SmartHeap does not work
In this case, SmartHeap symbols are not found when linking with 32-bit SmartHeap libraries (specifically SHDW3SMD.LIB).The version of SHDW3SMD.LIB shipped with SmartHeap is not usable. To create a usable one, perform this step to create a new library directly from the SmartHeap DLL:
implib /system shdw3smd.lib sh22w3sd.dll
Problem: Windows 3.1 functions undefined at link time
Some Windows 3.1 routines, such as GetCurrentTask(), are obsolete for Win32.You need to reengineer these routines. For information, see Microsoft Win32 API Programmer's Reference (available as the online Help file ..\dm\help\vc20bks4.hlp in Digital Mars C++).
Problem: ToolHelp functions undefined at link time
The Windows 3.1 ToolHelp library, which includes functions like ModuleFindHandle() and StackTraceNext(), is not available in Win32.You need to reengineer these routines. For information, see Microsoft Win32 API Programmer's Reference (available as the online Help file ..\dm\help\vc20bks4.hlp in Digital Mars C++).
Problem: Exported names not found
If this is a problem, the linker indicates that it cannot export any of the names in the .DEF file's export list, although the export list worked for Windows 3.1.Win32 defines PASCAL, WINAPI, and related functions as __stdcall; in Windows 3.1 they were defined as __pascal. This means that all PASCAL/ WINAPI functions now begin with an underscore (_) and are case-sensitive. Add underscores and change case in the export list as needed.
Problem: Names in .ASM files not found
If this is a problem, the linker indicates that it cannot fnd PASCAL names that are declared in .ASM files, although it could for Windows 3.1.Win32 defines PASCAL as __stdcall; in Windows 3.1 it was defined as __pascal. __stdcall functions begin with an underscore (_) and are case-sensitive. Add underscores and change case in the assembly language definitions of the affected functions.
Problem: DOS functions undefined in NT compilations
An example would be int86x and its parameter, union REGS, being undefined in a Windows NT compilation.Some DOS routines may need to be re-engineered using their Windows NT equivalents. For information, see Microsoft Win32 API Programmer's Reference (available as the online Help file ..\dm\help\vc20bks4.hlp in Digital Mars C++).
Problem: "FIXUPP" errors in 32-bit links
In this case, the linker generates an error for every reference to an external name in the build.You may be using outdated linker options. The Digital Mars C++ IDDE uses: /DO/DE/NT/Entry:__DllMainCRTStartup.
Problem: Assembler files don't link in Win32
In this case, assembly language code with .286 or 16-bit segments may not link.Recode affected files to remove 16-bit specific features. Note also that the use of segment registers is different for Win32 compilations.