"Weak External" Records: Description, Use, and Errors

ID: Q72651

5.05 5.1x 5.2x 5.3x 5.50 5.60 | 5.05 5.10 5.11 5.13 5.15

MS-DOS                        | OS/2

The information in this article applies to:

SUMMARY

A "weak external" is a special type of external reference that allows the linker to fix up an address with an alternate symbol. By using a weak external record, a library developer can provide a method for the linker to use an alternate symbol if the code does not make any other references to the module in which the primary symbol resides.

The Microsoft Incremental Linker (ILINK) does not support weak external records and returns the following message when it encounters one:

   fatal error L1246: weak externals not supported

To work around this situation, perform a full link.

MORE INFORMATION

Microsoft Macro Assembler (MASM) versions 6.0, 6.0a, 6.0b, and 6.1 support weak externals. When an application defines an EXTRN (or EXTERN in MASM 6.0 and above) you can also specify an alternate symbol. MASM accepts the alternate ID and creates in the object file both a standard EXTDEF record for the primary symbol and a COMENT record for the alternate symbol.

The COMENT record instructs LINK and the Microsoft Library utility (LIB) to treat the alternate symbol as a "weak" external reference. If the object file does not contain any other references to the module in which the standard symbol resides, LINK uses the weak external address to fix up the reference.

For example, some housekeeping functions for an application are developed in assembler and placed into a library. Another function calls the housekeeping functions, as in the following example:

   EXTRN _InitHeap:near   ; Use EXTERN in MASM 6.0 and above
   EXTRN _InitFile:near
   EXTRN _InitKbd:near

   InitLib PROC NEAR
      call _InitHeap
      call _InitFile
      call _InitKbd

   InitLib ENDP

Each of the functions (_InitHeap, _InitFile, and _InitKbd) resides in a module that defines the functions and symbols each subsystem uses. For example, the following LIB listing shows the contents of the module in which _InitKbd resides:

   KbdStuff          Offset: 00000010H  Code and data size: 915H
     _InitKbd          _ReadKey          _SendKey          _KeyBuffer
     _FlushKey         _ScanCode         _CharCode         _BiosState
     _Int16Handler     _CtrlBrkStat      _EchoState

If the program uses any function in the KbdStuff module, LINK places the entire module into the executable file. If the program does not use any of the other modules in KbdStuff, the _InitKbd function itself may not be required. Therefore, by using a regular EXTRN declaration, dead code (that is, the remainder of the KbdStuff module) is added to the executable file along with some executed code (_InitKbd) that is not necessary.

To avoid these effects, change this same example to use a weak external. Modify the EXTRN statement for _InitKbd to specify an alternate symbol, as follows:

   EXTRN _InitKbd(_EmptyInit):near

The _EmptyInit code is as follows:

   _EmptyInit PROC NEAR

      ret

   _EmptyInit ENDP

LINK can use the weak external _EmptyInit to resolve the reference to _InitKbd if the program does not refer to any of the other symbols in the KbdStuff module. If the program refers to some other symbols, LINK uses the original _InitKbd symbol.

The same logic applies to data symbols. For example, an application can set a flag to execute a given code path based on other modules that are linked into the application. As above, specify the default and alternate resolutions in the EXTRN statement and assemble the code. The linker uses the appropriate symbol.

However, if an application defines the same alternate reference with two different primary references in two separate modules, LINK generates the following message and LINK uses the default reference from the second module in both cases.

   warning L4067: changing default resolution for weak external
                  'symbol' from 'oldresolution' to 'newresolution'

The following code example demonstrates this situation:

MOD1.ASM

EXTRN Primary1(Alternate):near

MOD2.ASM

EXTRN Primary2(Alternate):near

For more information on the EXTRN directive, refer to the online help and to chapter 8 of the Microsoft Macro Assembler "Programmer's Guide" manual for versions 6.0 and 6.1.

For more information on the weak external (WKEXT) object record format, refer to the Microsoft "Relocatable Object Module Format".

An application note is available that describes the Microsoft relocatable object module format in detail.

In the United States, to obtain the "Microsoft Relocatable Object Module Format" application note, call Microsoft Product Support Services at (206) 454-2030. Outside the United States, contact the Microsoft subsidiary for your area. To locate your subsidiary, go to the Microsoft Web site http://www.microsoft.com/worldwide/default.htm

This application note is also available in the Microsoft Software Library and can be found by searching on the word SS0288, the Q number of this article, or S13472. SS0288 was archived using the PKware file-compression utility.

Additional reference words: kbinf kbinf 5.05 5.10 5.11 5.13 5.15 5.20 5.30 5.31.009 5.50 OMF KBCategory: KBSubcategory: LinkIss

Keywords          : kbcode kberrmsg kb16bitonly LinkIss 
Version           : 5.05 5.1x 5.2x 5.3x 5.50 5.60 |
Platform          : MS-DOS OS/2

Last Reviewed: May 22, 1998