Don't Use /ND on Modules with C Run-time Calls

Last reviewed: July 17, 1997
Article ID: Q72418
5.10 6.00 6.00a 6.00ax 7.00 | 5.10 6.00 6.00a | 1.00 1.50
MS-DOS                      | OS/2            | WINDOWS
kbprg

The information in this article applies to:

  • The C Run-time (CRT) included with:

        - Microsoft C for MS-DOS, versions 5.1, 6.0, 6.0a, and 6.0ax
        - Microsoft C for OS/2, versions 5.1, 6.0, and 6.0a
        - Microsoft C/C++ for MS-DOS, version 7.0
        - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    

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 example). 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: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00 8.00
KBCategory: kbprg
KBSubcategory: CRTIss
Keywords : kb16bitonly


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 17, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.