4.3 Mixing Memory Models

In standard memory models, explained in the preceding section, all data pointers are the same size and all code pointers are the same size.

A mixed memory model selectively combines different types of pointers within the same program. A mixed model extends the limits of a given memory model while retaining its benefits.

For example, imagine a programming situation in which you add an array to a small-model program, pushing the data segment past the 64K limit.

You could solve the problem by moving up from the small to the compact memory model. Doing so would bump all data pointers from two to four bytes. The .EXE file would grow accordingly. Execution time would slow.

Summary: A mixed memory model lets you mix near and far pointers.

A second and perhaps better solution is to stay within the standard small memory model, which uses near pointers, but to declare the new array as far. You mix near pointers and far pointers, creating a mixed model.

Microsoft C/C++ lets you override the standard addressing convention for a given memory model by specifying that certain items are __near, __far, __huge, or __based. These keywords are not a standard part of the C language; they are Microsoft extensions, meaningful only on systems that use 80x86 microprocessors. Using these keywords may affect the portability of your code.

Note:

Previous versions of the Microsoft C Compiler accepted the keywords near, far, and huge without an initial underscore, as well as with a single underscore. Since the ANSI standard for C permits compiler implementors to reserve keywords that begin with two underscores, all Microsoft-specific keywords have two initial underscores. To maintain compatibility with existing source code, the compiler still recognizes the obsolescent versions of these keywords.

You can compile a program in the small model, for example, but declare a certain array to be __far. At run time, the address of that array occupies four bytes. The program may slow slightly when accessing items in that particular far array, but throughout the rest of the program, all addressing would be near. Note that all pointers to elements of an array declared as __far must also be declared as __far.

Table 4.2 lists the effects of these keywords on data pointers, code pointers, and pointer arithmetic.

Table 4.2 Addressing Declared with Microsoft Keywords

Keyword Data Code Arithmetic

__near Data reside in default data segment; 16-bit addresses, Functions reside in current code segment; 16-bit addresses 16 bits  
__far Data can be anywhere in memory, not necessarily in the default data segment; 32-bit addresses Functions can be called from anywhere in memory; 32-bit addresses 16 bits
__huge Data can be anywhere in memory, not necessarily in the default data segment. Individual data items (arrays) can exceed 64K in size; 32-bit addresses Not applicable; code cannot be declared __huge 32 bits (data only)
__based Data can be anywhere in memory, not necessarily in the default data segment; 16-bit addresses plus a known base provide the range of 32-bit addresses Functions reside in specified code segment; can be used with __near or __far 16 bits