PRB: /ND Shouldn't Be Used on Modules with C Run-time Calls

ID Number: Q72418

5.10 6.00 6.00a 6.00ax 7.00 | 5.10 6.00 6.00a

MS-DOS | OS/2

Summary:

In most cases, the /ND (name data segment) compiler option should not

be used on any module that contains calls to the C run-time library,

or fatal program errors will result. The C run-time code attempts to

access data in the wrong segment, generating a protection violation

(GP fault) under OS/2 or possibly hanging the system under MS-DOS.

More Information:

The /ND switch may be used to generate a default data segment of a

particular name. This is desirable in many situations in order to

control data segment names (creating a shared segment, for instance).

When /ND is used, the compiler creates three segments (dataname,

dataname_BSS, and dataname_CONST), makes them a part of a new group

(dataname_GROUP), and performs an explicit DS load with the new

default data segment for every function defined in the module.

This can cause problems when the C run-time library is used. The

run-time library is built with the assumption that DS points to the

default data segment for the entire application (DGROUP). This allows

the C run-time to use near pointers to access its internal data

structures because it assumes that this data is based in the default

data segment. When you use /ND on a module that contains run-time

code, DS is not set to the correct segment and the run-time data will

not be accessed correctly.

Therefore, if you require the /ND switch for your application, do not

use it on a module with run-time calls. The best solution is to create

a module that defines data only, and compile it with /ND. The rest of

your modules can use "extern" references to access that data. In this

manner, you can have the benefits of naming your data segments without

causing problems with the run-time library. The sample code below

illustrates this method.

The CDLLOBJS library (C run time in a DLL) is not subject to these

restrictions. In this implementation alone, DS is loaded with the

application's default data segment (DGROUP) inside the run-time code.

Sample Code #1

--------------

/* Compile the following modules as indicated and then link the

resulting .OBJ files together (for example, LINK code data;).

*/

/* Module 1 - DATA.C */

/* Compile options needed: /c /ND MYDATA

*/

char array[] = "This is defined in the MYDATA data segment";

Sample Code #2

--------------

/* Module 2 - CODE.C */

/* Compile options needed: /c

*/

extern char _far array[];

void main(void)

{

printf("The string in MYDATA is: %Fs\n", array);

}

Additional reference words: 6.00 6.00a 6.00ax