home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / books / cadvprg.db < prev    next >
Encoding:
Text File  |  1991-03-01  |  1013.0 KB  |  20,727 lines

  1. %@1@%%@AB@%Microsoft  C - Advanced Programming Techniques%@AE@%%@EH@%%@NL@%
  2.                                       %@NL@%
  3.                                       %@NL@%
  4.                                       %@NL@%
  5.                                       %@NL@%
  6.                                       %@NL@%
  7.                                       %@NL@%
  8.                                       %@NL@%
  9.  
  10. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11.              %@AB@%Microsoft (R) C - Advanced Programming Techniques%@AE@%%@NL@%
  12.                                       %@NL@%
  13.                        %@AB@%FOR MS (R) OS/2 AND MS-DOS (R)
  14.                              %@AB@%OPERATING SYSTEMS%@AE@%%@NL@%
  15. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16.                                       %@NL@%
  17.                                       %@NL@%
  18.                            MICROSOFT CORPORATION%@NL@%
  19.                                       %@NL@%
  20. %@NL@%
  21. %@NL@%
  22. %@NL@%
  23. %@NL@%%@NL@%
  24. %@NL@%
  25.  
  26.  
  27. Information in this document is subject to change without notice and does
  28. not represent a commitment on the part of Microsoft Corporation. The
  29. software described in this document is furnished under a license agreement
  30. or nondisclosure agreement. The software may be used or copied only in
  31. accordance with the terms of the agreement. It is against the law to copy
  32. the software on any medium except as specifically allowed in the license or
  33. nondisclosure agreement. No part of this manual may be reproduced or trans-
  34. mitted in any form or by any means, electronic or mechanical, including
  35. photocopying and recording, for any purpose without the express written
  36. permission of Microsoft.
  37.  
  38. (C) Copyright Microsoft Corporation, 1990. All rights reserved.%@NL@%
  39. %@NL@%
  40. Printed and bound in the United States of America.%@NL@%
  41. %@NL@%
  42. Microsoft, MS, MS-DOS, CodeView, InPort, and XENIX are 
  43. registered trademarks and Windows is a trademark of Microsoft Corporation.%@NL@%
  44. %@NL@%
  45. Apple and Macintosh are registered trademarks and Finder 
  46. is a trademark of Apple Computer, Inc.%@NL@%
  47. %@NL@%
  48. AT&T is a registered trademark of American Telephone 
  49. and Telegraph Company.%@NL@%
  50. %@NL@%
  51. Hercules is a registered trademark and InColor is a trademark 
  52. of Hercules Computer Technology.%@NL@%
  53. %@NL@%
  54. IBM is a registered trademark of International Business 
  55. Machines Corporation.%@NL@%
  56. %@NL@%
  57. Intel is a registered trademark of Intel Corporation.%@NL@%
  58. %@NL@%
  59. Olivetti is a registered trademark of Ing. C. Olivetti.%@NL@%
  60. %@NL@%
  61. PDP-11 and VAX-11 are registered trademarks of Digital 
  62. Equipment Corporation.%@NL@%
  63. %@NL@%
  64. WANG is a registered trademark of Wang Laboratories.%@NL@%
  65. %@NL@%
  66. Z8000 is a registered trademark of Zilog, Inc.%@NL@%
  67. %@NL@%
  68. Document No. LN06514-1189 OEMO711-6Z
  69. 10 9 8 7 6 5 4 3 2 1 %@NL@%
  70. %@NL@%
  71. %@NL@%
  72. %@NL@%
  73. %@NL@%
  74. %@1@%%@AB@%Table of Contents%@AE@%%@EH@%%@NL@%
  75. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  76. %@NL@%
  77.  
  78. %@NL@%
  79. %@AB@%Introduction%@AE@%%@BO:        9686@%%@NL@%
  80.      Scope of This Book%@BO:        bdfd@%%@NL@%
  81.      Document Conventions%@BO:        a897@%%@NL@%
  82. %@NL@%
  83. %@NL@%
  84. %@AB@%PART I%@AE@%%@BO:        b991@%  %@AB@%Improving Program Performance%@AE@%%@NL@%
  85. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  86. %@NL@%
  87. %@NL@%
  88. %@AB@%Chapter 1%@AE@%%@BO:        bdfd@%  %@AB@%Optimizing C Programs%@AE@%%@NL@%
  89. %@NL@%
  90.      1.1%@BO:        a897@%   Controlling Optimization from the Programmer's WorkBench%@NL@%
  91.      1.2%@BO:        c938@%   Controlling Optimization from the Command Line%@NL@%
  92.      1.3%@BO:        ccf7@%   Controlling Optimization with Pragmas%@NL@%
  93.      1.4%@BO:        d6d0@%   Default Optimization%@NL@%
  94.             1.4.1%@BO:        d898@%    Common Subexpression Elimination%@NL@%
  95.             1.4.2%@BO:        db9a@%    Dead-Store Elimination%@NL@%
  96.             1.4.3%@BO:        de12@%    Constant Propagation%@NL@%
  97.      1.5%@BO:        e451@%   Customizing Your Optimizations%@NL@%
  98.             1.5.1%@BO:        e5c6@%    Choosing Speed or Size (/Ot and /Os)%@NL@%
  99.             1.5.2%@BO:        ea01@%    Generating Intrinsic Functions (/Oi)%@NL@%
  100.             1.5.3%@BO:       107f9@%    Assuming No Aliasing (/Oa and /Ow)%@NL@%
  101.             1.5.4%@BO:       1212b@%    Performing Loop Optimizations (/Ol)%@NL@%
  102.             1.5.5%@BO:       12e46@%    Disabling Unsafe Loop Optimizations (/On)%@NL@%
  103.             1.5.6%@BO:       12ff7@%    Enabling Aggressive Optimizations (/Oz)%@NL@%
  104.             1.5.7%@BO:       13a0d@%    Removing Stack Probes (/Gs)%@NL@%
  105.             1.5.8%@BO:       13daa@%    Enabling Global Register Allocation (/Oe)%@NL@%
  106.             1.5.9%@BO:       14925@%    Enabling Common Subexpression Optimization (/Oc and 
  107.                         /Og)%@NL@%
  108.             1.5.10%@BO:       14e06@%   Achieving Consistent Floating-Point Results (/Op)%@NL@%
  109.             1.5.11%@BO:       15770@%   Using the 80186, 80188, or 80286 Processor (/G0, /G1,
  110.                         /G2)%@NL@%
  111.             1.5.12%@BO:       15f38@%   Optimizing for Maximum Efficiency (/Ox)%@NL@%
  112.      1.6%@BO:       1651b@%   Linker (LINK) Options that Control Optimization%@NL@%
  113.             1.6.1%@BO:       1666f@%    Enabling Far Call Optimization (/FARCALLTRANSLATION)%@NL@%
  114.             1.6.2%@BO:       17905@%    Packing Code (/PACKCODE)%@NL@%
  115.             1.6.3%@BO:       17f5b@%    Packing Data (/PACKDATA)%@NL@%
  116.             1.6.4%@BO:       183a0@%    Packing the Executable File (/EXEPACK)%@NL@%
  117.      1.7%@BO:       18674@%   Optimizing in Different Environments%@NL@%
  118.             1.7.1%@BO:       18764@%    Optimizing in DOS%@NL@%
  119.             1.7.2%@BO:       188d6@%    Optimizing in OS/2%@NL@%
  120.             1.7.3%@BO:       189dc@%    Optimizing in Microsoft Windows(tm)%@NL@%
  121.      1.8%@BO:       18c3f@%   Choosing Function-Calling Conventions%@NL@%
  122.             1.8.1%@BO:       18f7f@%    The C Calling Convention (/Gd)%@NL@%
  123.             1.8.2%@BO:       1932b@%    The FORTRAN/Pascal Calling Convention (/Gc)%@NL@%
  124.             1.8.3%@BO:       19971@%    The Register Calling Convention (/Gr)%@NL@%
  125.             1.8.4%@BO:       19f58@%    The _fastcall Calling Convention%@NL@%
  126. %@NL@%
  127. %@AB@%Chapter 2%@AE@%%@BO:       1b75b@%  %@AB@%Managing Memory%@AE@%%@NL@%
  128. %@NL@%
  129.      2.1%@BO:       1bb95@%   Pointer Sizes%@NL@%
  130.             2.1.1%@BO:       1bdf8@%    Pointers and 64K Segments%@NL@%
  131.             2.1.2%@BO:       1c3da@%    Near Pointers%@NL@%
  132.             2.1.3%@BO:       1c68e@%    Far Pointers%@NL@%
  133.             2.1.4%@BO:       1ca77@%    Huge Pointers%@NL@%
  134.             2.1.5%@BO:       1d06e@%    Based Addressing%@NL@%
  135.      2.2%@BO:       1d327@%   Selecting a Standard Memory Model%@NL@%
  136.             2.2.1%@BO:       1d70e@%    The Six Standard Memory Models%@NL@%
  137.             2.2.2%@BO:       1dc36@%    Limitations on Code Size and Data Size%@NL@%
  138.             2.2.3%@BO:       1de9f@%    The Tiny Memory Model%@NL@%
  139.             2.2.4%@BO:       1e27d@%    The Huge Memory Model%@NL@%
  140.             2.2.5%@BO:       1ed27@%    Null Pointers%@NL@%
  141.             2.2.6%@BO:       1f5f0@%    Specifying a Memory Model%@NL@%
  142.      2.3%@BO:       1fcb2@%   Mixing Memory Models%@NL@%
  143.             2.3.1%@BO:       2101e@%    Pointer Problems%@NL@%
  144.             2.3.2%@BO:       21b7c@%    Declaring Near, Far, Huge, and Based Variables%@NL@%
  145.             2.3.3%@BO:       2249a@%    Declaring Near and Far Functions%@NL@%
  146.             2.3.4%@BO:       23064@%    Pointer Conversions%@NL@%
  147.      2.4%@BO:       24124@%   Customizing Memory Models%@NL@%
  148.             2.4.1%@BO:       249f8@%    Setting a Size for Code Pointers%@NL@%
  149.             2.4.2%@BO:       24d6d@%    Setting a Size for Data Pointers%@NL@%
  150.             2.4.3%@BO:       2530c@%    Setting Up Segments%@NL@%
  151.             2.4.4%@BO:       26cc4@%    Library Support for Customized Memory Models%@NL@%
  152.             2.4.5%@BO:       272c9@%    Setting the Data Threshold%@NL@%
  153.             2.4.6%@BO:       27753@%    Naming Modules and Segments%@NL@%
  154. %@NL@%
  155. %@AB@%Chapter 3%@AE@%%@BO:       283e2@%  %@AB@%Using the In-Line Assembler%@AE@%%@NL@%
  156. %@NL@%
  157.      3.1%@BO:       28684@%   Advantages of In-Line Assembly%@NL@%
  158.      3.2%@BO:       28b7b@%   The _asm Keyword%@NL@%
  159.      3.3%@BO:       29386@%   Using Assembly Language in _asm Blocks%@NL@%
  160.      3.4%@BO:       2aeac@%   Using C in _asm Blocks%@NL@%
  161.             3.4.1%@BO:       2b3b3@%    Using Operators%@NL@%
  162.             3.4.2%@BO:       2b8db@%    Using C Symbols%@NL@%
  163.             3.4.3%@BO:       2bd9d@%    Accessing C Data%@NL@%
  164.             3.4.4%@BO:       2c544@%    Writing Functions%@NL@%
  165.      3.5%@BO:       2d276@%   Using and Preserving Registers%@NL@%
  166.      3.6%@BO:       2dfda@%   Jumping to Labels%@NL@%
  167.      3.7%@BO:       2e897@%   Calling C Functions%@NL@%
  168.      3.8%@BO:       2ed4b@%   Defining _asm Blocks as C Macros%@NL@%
  169.      3.9%@BO:       2fc28@%   Optimizing%@NL@%
  170. %@NL@%
  171. %@AB@%Chapter 4%@AE@%%@BO:       306b8@%  %@AB@%Controlling Floating-Point Math Operations%@AE@%%@NL@%
  172. %@NL@%
  173.      4.1%@BO:       30a74@%   Declaring Floating-Point Types%@NL@%
  174.             4.1.1%@BO:       30d03@%    Declaring Variables as Floating-Point Types%@NL@%
  175.             4.1.2%@BO:       32643@%    Declaring Functions that Return Floating-Point Types%@NL@%
  176.      4.2%@BO:       32d2a@%   C Run-Time Library Support of Type long double%@NL@%
  177.      4.3%@BO:       3307c@%   Summary of Math Packages%@NL@%
  178.             4.3.1%@BO:       3376a@%    Emulator Package%@NL@%
  179.             4.3.2%@BO:       33f87@%    Math Coprocessor Package%@NL@%
  180.             4.3.3%@BO:       341c5@%    Alternate Math Package%@NL@%
  181.      4.4%@BO:       34641@%   Selecting Floating-Point Options (/FP)%@NL@%
  182.             4.4.1%@BO:       366b7@%    In-Line Emulator Option (/FPi)%@NL@%
  183.             4.4.2%@BO:       36f6a@%    In-Line Math Coprocessor Instructions Option (/FPi87)%@NL@%
  184.             4.4.3%@BO:       3737c@%    Calls to Emulator Option (/FPc)%@NL@%
  185.             4.4.4%@BO:       37927@%    Calls to Math Coprocessor Option (/FPc87)%@NL@%
  186.             4.4.5%@BO:       3826d@%    Use Alternate Math Option (/FPa)%@NL@%
  187.      4.5%@BO:       386a4@%   Library Considerations for Floating-Point Options%@NL@%
  188.             4.5.1%@BO:       3899b@%    Using One Standard Library for Linking%@NL@%
  189.             4.5.2%@BO:       38cfd@%    In-Line Instructions or Calls%@NL@%
  190.      4.6%@BO:       3913f@%   Compatibility between Floating-Point Options%@NL@%
  191.      4.7%@BO:       39a6a@%   Using the NO87 Environment Variable%@NL@%
  192.      4.8%@BO:       3a2a8@%   Incompatibility Issues%@NL@%
  193. %@NL@%
  194. %@NL@%
  195. %@AB@%PART II%@AE@%%@BO:       3a90c@%  %@AB@%Improving Programmer Productivity%@AE@%%@NL@%
  196. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  197. %@NL@%
  198. %@NL@%
  199. %@AB@%Chapter 5%@AE@%%@BO:       3ada9@%  %@AB@%Compiling and Linking Quickly%@AE@%%@NL@%
  200. %@NL@%
  201.      5.1%@BO:       3afdd@%   Compiling Quickly%@NL@%
  202.             5.1.1%@BO:       3b0c7@%    Quick Compiler%@NL@%
  203.             5.1.2%@BO:       3b47a@%    Incremental Compile Option%@NL@%
  204.      5.2%@BO:       3b7b3@%   Linking Quickly with ILINK%@NL@%
  205.             5.2.1%@BO:       3bf41@%    Preparing for Incremental Linking%@NL@%
  206.             5.2.2%@BO:       3cae1@%    Incremental Violations%@NL@%
  207. %@NL@%
  208. %@AB@%Chapter 6%@AE@%%@BO:       3d5e2@%  %@AB@%Managing Development Projects with NMAKE%@AE@%%@NL@%
  209. %@NL@%
  210.      6.1%@BO:       3da36@%   Overview of NMAKE%@NL@%
  211.      6.2%@BO:       3de62@%   The NMAKE Command%@NL@%
  212.      6.3%@BO:       3e70a@%   NMAKE Description Files%@NL@%
  213.             6.3.1%@BO:       3e89a@%    Description Blocks%@NL@%
  214.             6.3.2%@BO:       4157f@%    Comments%@NL@%
  215.             6.3.3%@BO:       4174e@%    Macros%@NL@%
  216.             6.3.4%@BO:       45bdb@%    Inference Rules%@NL@%
  217.             6.3.5%@BO:       473c7@%    Directives%@NL@%
  218.             6.3.6%@BO:       48e0c@%    Pseudotargets%@NL@%
  219.             6.3.7%@BO:       49ebe@%    PWB's extmake Syntax%@NL@%
  220.      6.4%@BO:       4a5bf@%   Command-Line Options%@NL@%
  221.      6.5%@BO:       4b91e@%   NMAKE Command Files%@NL@%
  222.      6.6%@BO:       4bef2@%   The TOOLS.INI File%@NL@%
  223.      6.7%@BO:       4c2bc@%   In-Line Files%@NL@%
  224.      6.8%@BO:       4cb4d@%   NMAKE Operations Sequence%@NL@%
  225.      6.9%@BO:       4de57@%   Differences between NMAKE and MAKE%@NL@%
  226. %@NL@%
  227. %@AB@%Chapter 7%@AE@%%@BO:       4ed59@%  %@AB@%Creating Help Files with HELPMAKE%@AE@%%@NL@%
  228. %@NL@%
  229.      7.1%@BO:       4f180@%   Structure and Contents of a Help Database%@NL@%
  230.             7.1.1%@BO:       4f2e4@%    Contents of a Help File%@NL@%
  231.             7.1.2%@BO:       5028d@%    Help File Formats%@NL@%
  232.      7.2%@BO:       50e99@%   Invoking HELPMAKE%@NL@%
  233.      7.3%@BO:       51889@%   HELPMAKE Options%@NL@%
  234.             7.3.1%@BO:       51a53@%    Options for Encoding%@NL@%
  235.             7.3.2%@BO:       543d4@%    Options for Decoding%@NL@%
  236.      7.4%@BO:       558a5@%   Creating a Help Database%@NL@%
  237.      7.5%@BO:       55ed3@%   Help Text Conventions%@NL@%
  238.             7.5.1%@BO:       55fed@%    Structure of the Help Text File%@NL@%
  239.             7.5.2%@BO:       56806@%    Local Contexts%@NL@%
  240.             7.5.3%@BO:       56dec@%    Context Prefixes%@NL@%
  241.             7.5.4%@BO:       582a4@%    Hyperlinks%@NL@%
  242.      7.6%@BO:       5932f@%   Using Help Database Formats%@NL@%
  243.             7.6.1%@BO:       59b21@%    QuickHelp Format%@NL@%
  244.             7.6.2%@BO:       5db23@%    Minimally Formatted ASCII Format%@NL@%
  245.             7.6.3%@BO:       5e410@%    Rich Text Format (RTF)%@NL@%
  246. %@NL@%
  247. %@AB@%Chapter 8%@AE@%%@BO:       5f750@%  %@AB@%Customizing the Microsoft Programmer's WorkBench%@AE@%%@NL@%
  248. %@NL@%
  249.      8.1%@BO:       5fc26@%   Setting Switches%@NL@%
  250.             8.1.1%@BO:       5fe49@%    Editing the <assign> Pseudofile%@NL@%
  251.             8.1.2%@BO:       604db@%    Editing the TOOLS.INI Initialization File%@NL@%
  252.      8.2%@BO:       610f5@%   Assigning Keystrokes%@NL@%
  253.      8.3%@BO:       619e7@%   Writing Macros%@NL@%
  254.             8.3.1%@BO:       61b24@%    Macro Syntax%@NL@%
  255.             8.3.2%@BO:       6270b@%    Macro Responses%@NL@%
  256.             8.3.3%@BO:       62dd1@%    Macro Arguments%@NL@%
  257.             8.3.4%@BO:       63473@%    Macro Conditionals%@NL@%
  258.             8.3.5%@BO:       63da5@%    Temporary Macros%@NL@%
  259.             8.3.6%@BO:       640d2@%    Macro Recordings%@NL@%
  260.      8.4%@BO:       64b33@%   Writing and Building C Extensions%@NL@%
  261.             8.4.1%@BO:       65cb5@%    Building Real-Mode Extensions%@NL@%
  262.             8.4.2%@BO:       667cc@%    Building Protected-Mode Extensions%@NL@%
  263.             8.4.3%@BO:       67183@%    Describing Functions and Switches%@NL@%
  264.             8.4.4%@BO:       689a6@%    Initializing Functions%@NL@%
  265.             8.4.5%@BO:       68d27@%    Prototyping Functions%@NL@%
  266.             8.4.6%@BO:       69122@%    Receiving Parameters%@NL@%
  267.             8.4.7%@BO:       6a36d@%    Calling PWB Functions%@NL@%
  268.             8.4.8%@BO:       6c45b@%    Calling C Library Functions%@NL@%
  269. %@NL@%
  270. %@AB@%Chapter 9%@AE@%%@BO:       6cc79@%  %@AB@%Debugging C Programs with CodeView%@AE@%%@NL@%
  271. %@NL@%
  272.      9.1%@BO:       6d0c1@%   Understanding CodeView Windows%@NL@%
  273.      9.2%@BO:       6e652@%   Overview of Debugging Techniques%@NL@%
  274.      9.3%@BO:       6ec41@%   Viewing and Modifying Program Data%@NL@%
  275.             9.3.1%@BO:       6edbe@%    Displaying Variables in the Watch Window%@NL@%
  276.             9.3.2%@BO:       6f66e@%    Displaying Expressions in the Watch Window%@NL@%
  277.             9.3.3%@BO:       6fd74@%    Displaying Arrays and Structures%@NL@%
  278.             9.3.4%@BO:       70e92@%    Displaying Array Elements Dynamically%@NL@%
  279.             9.3.5%@BO:       711f8@%    Using Quick Watch%@NL@%
  280.             9.3.6%@BO:       717dc@%    Displaying Memory%@NL@%
  281.             9.3.7%@BO:       72653@%    Displaying the Processor Registers%@NL@%
  282.             9.3.8%@BO:       72b9c@%    Modifying the Values of Variables, Registers,
  283.                         and Memory%@NL@%
  284.      9.4%@BO:       733af@%   Controlling Execution%@NL@%
  285.             9.4.1%@BO:       735dc@%    Continuous Execution%@NL@%
  286.             9.4.2%@BO:       75665@%    Single-Stepping%@NL@%
  287.      9.5%@BO:       75bf1@%   Replaying a Debug Session%@NL@%
  288.      9.6%@BO:       769d2@%   Advanced CodeView Techniques%@NL@%
  289.      9.7%@BO:       78caf@%   Controlling CodeView with Command-Line Options%@NL@%
  290.      9.8%@BO:       79ca7@%   Customizing CodeView with the TOOLS.INI FILE%@NL@%
  291. %@NL@%
  292. %@NL@%
  293. %@AB@%PART III%@AE@%%@BO:       7a0b5@%  %@AB@%Special Environments%@AE@%%@NL@%
  294. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  295. %@NL@%
  296. %@NL@%
  297. %@AB@%Chapter 10%@AE@%%@BO:       7a411@%  %@AB@%Communicating with Graphics%@AE@%%@NL@%
  298. %@NL@%
  299.      10.1%@BO:       7a96d@%  Video Modes%@NL@%
  300.             10.1.1%@BO:       7aed0@%    Sample Low-Level Graphics Program%@NL@%
  301.             10.1.2%@BO:       7b97c@%    Setting a Video Mode%@NL@%
  302.             10.1.3%@BO:       7c764@%    Reading the videoconfig Structure%@NL@%
  303.             10.1.4%@BO:       7d113@%    Maximizing Resolution or Color%@NL@%
  304.             10.1.5%@BO:       7d740@%    Selecting Your Own Video Modes%@NL@%
  305.      10.2%@BO:       7dc0f@%  Mixing Colors and Changing Palettes%@NL@%
  306.             10.2.1%@BO:       7e2a7@%    CGA Palettes%@NL@%
  307.             10.2.2%@BO:       7ec93@%    Olivetti(R) Palettes%@NL@%
  308.             10.2.3%@BO:       7ef5d@%    VGA Palettes%@NL@%
  309.             10.2.4%@BO:       7fb3a@%    MCGA Palettes%@NL@%
  310.             10.2.5%@BO:       7fcaa@%    EGA Palettes%@NL@%
  311.             10.2.6%@BO:       801b2@%    Symbolic Constants%@NL@%
  312.      10.3%@BO:       80592@%  Specifying Points within Coordinate Systems%@NL@%
  313.             10.3.1%@BO:       8099d@%    Physical Coordinates%@NL@%
  314.             10.3.2%@BO:       812e6@%    Viewport Coordinates%@NL@%
  315.             10.3.3%@BO:       81890@%    Window Coordinates%@NL@%
  316.             10.3.4%@BO:       81ee4@%    Screen Locations%@NL@%
  317.             10.3.5%@BO:       823fa@%    Bounding Rectangles%@NL@%
  318.             10.3.6%@BO:       82781@%    The Pixel Cursor%@NL@%
  319.      10.4%@BO:       82a7b@%  Graphics Functions%@NL@%
  320.             10.4.1%@BO:       82cc4@%    Controlling Video Modes%@NL@%
  321.             10.4.2%@BO:       83c39@%    Changing Colors%@NL@%
  322.             10.4.3%@BO:       844c2@%    Drawing Points, Lines, and Shapes%@NL@%
  323.             10.4.4%@BO:       859c2@%    Defining Patterns%@NL@%
  324.             10.4.5%@BO:       86184@%    Manipulating Images%@NL@%
  325.      10.5%@BO:       86bee@%  Using Graphic Fonts%@NL@%
  326.             10.5.1%@BO:       877ab@%    Using the C Font Library%@NL@%
  327.             10.5.2%@BO:       87c1d@%    Registering the Fonts%@NL@%
  328.             10.5.3%@BO:       88036@%    Setting the Current Font%@NL@%
  329.             10.5.4%@BO:       896c0@%    Displaying Text%@NL@%
  330.             10.5.5%@BO:       898aa@%    A Sample Program%@NL@%
  331.             10.5.6%@BO:       8a3d5@%    Using Fonts Effectively%@NL@%
  332. %@NL@%
  333. %@AB@%Chapter 11%@AE@%%@BO:       8aaf4@%  %@AB@%Creating Charts and Graphs%@AE@%%@NL@%
  334. %@NL@%
  335.      11.1%@BO:       8ae04@%  Overview of Presentation Graphics%@NL@%
  336.      11.2%@BO:       8b7df@%  Parts of a Graph%@NL@%
  337.      11.3%@BO:       8d6ab@%  Writing a Presentation Graphics Program%@NL@%
  338.             11.3.1%@BO:       8ddc9@%    Pie Chart%@NL@%
  339.             11.3.2%@BO:       8e7dc@%    Bar, Column, and Line Charts%@NL@%
  340.             11.3.3%@BO:       8f968@%    Scatter Diagram%@NL@%
  341.      11.4%@BO:       90562@%  Manipulating Colors and Patterns%@NL@%
  342.             11.4.1%@BO:       90ad9@%    Color Pool%@NL@%
  343.             11.4.2%@BO:       91535@%    Style Pool%@NL@%
  344.             11.4.3%@BO:       91a9b@%    Pattern Pool%@NL@%
  345.             11.4.4%@BO:       92c2b@%    Character Pool%@NL@%
  346.      11.5%@BO:       92dd5@%  Customizing the Chart Environment%@NL@%
  347.             11.5.1%@BO:       93be0@%    titletype Structures%@NL@%
  348.             11.5.2%@BO:       9459e@%    axistype Structures%@NL@%
  349.             11.5.3%@BO:       976d0@%    windowtype Structures%@NL@%
  350.             11.5.4%@BO:       98696@%    legendtype Structures%@NL@%
  351.             11.5.5%@BO:       9967d@%    chartenv Structures%@NL@%
  352. %@NL@%
  353. %@AB@%Chapter 12%@AE@%%@BO:       9aa24@%  %@AB@%Programming with Mixed Languages%@AE@%%@NL@%
  354. %@NL@%
  355.      12.1%@BO:       9ad4c@%  Making Mixed-Language Calls%@NL@%
  356.      12.2%@BO:       9ba76@%  Language Convention Requirements%@NL@%
  357.             12.2.1%@BO:       9bca6@%    Naming Convention Requirement%@NL@%
  358.             12.2.2%@BO:       9cfc0@%    Calling Convention Requirement%@NL@%
  359.             12.2.3%@BO:       9e1fd@%    Parameter-Passing Requirement%@NL@%
  360.      12.3%@BO:       9f253@%  Compiling and Linking%@NL@%
  361.             12.3.1%@BO:       9f3b2@%    Compiling with Correct Memory Models%@NL@%
  362.             12.3.2%@BO:       9f9ac@%    Linking with Language Libraries%@NL@%
  363.      12.4%@BO:       a0128@%  C Calls to High-Level Languages%@NL@%
  364.      12.5%@BO:       a1883@%  C Calls to BASIC%@NL@%
  365.      12.6%@BO:       a2cd2@%  C Calls to FORTRAN%@NL@%
  366.             12.6.1%@BO:       a2e7e@%    Calling a FORTRAN Subroutine from C%@NL@%
  367.             12.6.2%@BO:       a3920@%    Calling a FORTRAN Function from C%@NL@%
  368.      12.7%@BO:       a4226@%  C Calls to Pascal%@NL@%
  369.             12.7.1%@BO:       a43cc@%    Calling a Pascal Procedure from C%@NL@%
  370.             12.7.2%@BO:       a4d77@%    Calling a Pascal Function from C%@NL@%
  371.      12.8%@BO:       a5596@%  C Calls to Assembly Language%@NL@%
  372.             12.8.1%@BO:       a5da1@%    Writing the Assembly-Language Procedure%@NL@%
  373.             12.8.2%@BO:       a6312@%    Setting Up the Procedure%@NL@%
  374.             12.8.3%@BO:       a6aae@%    Entering the Procedure%@NL@%
  375.             12.8.4%@BO:       a6f57@%    Allocating Local Data%@NL@%
  376.             12.8.5%@BO:       a7510@%    Preserving Register Values%@NL@%
  377.             12.8.6%@BO:       a802c@%    Accessing Parameters%@NL@%
  378.             12.8.7%@BO:       a8e40@%    Returning a Value%@NL@%
  379.             12.8.8%@BO:       a9a4d@%    Exiting the Procedure%@NL@%
  380.      12.9%@BO:       aa24b@%  Handling Data in Mixed-Language Programming%@NL@%
  381.             12.9.1%@BO:       aa39c@%    Default Naming and Calling Conventions%@NL@%
  382.             12.9.2%@BO:       aacde@%    Numeric Data Representation%@NL@%
  383.             12.9.3%@BO:       ab885@%    Strings%@NL@%
  384.             12.9.4%@BO:       ad1db@%    Arrays%@NL@%
  385.             12.9.5%@BO:       ad98d@%    Array Declaration and Indexing%@NL@%
  386.             12.9.6%@BO:       ae795@%    Structures, Records, and User-Defined Types%@NL@%
  387.             12.9.7%@BO:       aeec0@%    External Data%@NL@%
  388.             12.9.8%@BO:       af676@%    Pointers and Address Variables%@NL@%
  389.             12.9.9%@BO:       afe32@%    Common Blocks%@NL@%
  390.             12.9.10%@BO:       b08e9@%   Using a Varying Number of Parameters%@NL@%
  391. %@NL@%
  392. %@AB@%Chapter 13%@AE@%%@BO:       b0c3c@%  %@AB@%Writing Portable Programs%@AE@%%@NL@%
  393. %@NL@%
  394.      13.1%@BO:       b1007@%  Assumptions about Hardware%@NL@%
  395.             13.1.1%@BO:       b1169@%    Size of Basic Types%@NL@%
  396.             13.1.2%@BO:       b3a6e@%    Storage Order and Alignment%@NL@%
  397.             13.1.3%@BO:       b4c9f@%    Byte Order in a Word%@NL@%
  398.             13.1.4%@BO:       b58da@%    Reading and Writing Structures%@NL@%
  399.             13.1.5%@BO:       b5c84@%    Bit Fields in Structures%@NL@%
  400.             13.1.6%@BO:       b6909@%    Processor Arithmetic Mode%@NL@%
  401.             13.1.7%@BO:       b6f0a@%    Pointers%@NL@%
  402.             13.1.8%@BO:       b83ac@%    Address Space%@NL@%
  403.             13.1.9%@BO:       b8a46@%    Character Set%@NL@%
  404.      13.2%@BO:       b962b@%  Assumptions about the Compiler%@NL@%
  405.             13.2.1%@BO:       b9892@%    Sign Extension%@NL@%
  406.             13.2.2%@BO:       bab57@%    Length and Case of Identifiers%@NL@%
  407.             13.2.3%@BO:       bb247@%    Register Variables%@NL@%
  408.             13.2.4%@BO:       bb8b1@%    Functions with a Variable Number of Arguments%@NL@%
  409.             13.2.5%@BO:       bbbc6@%    Evaluation Order%@NL@%
  410.             13.2.6%@BO:       bc416@%    Function and Macro Arguments with Side Effects%@NL@%
  411.             13.2.7%@BO:       bcd8f@%    Environment Differences%@NL@%
  412.      13.3%@BO:       bd133@%  Portability of Data Files%@NL@%
  413.      13.4%@BO:       bd422@%  Portability Concerns Specific to Microsoft C%@NL@%
  414.      13.5%@BO:       bd7f3@%  Microsoft C Byte Ordering%@NL@%
  415. %@NL@%
  416. %@NL@%
  417. %@AB@%PART IV%@AE@%%@BO:       bde61@%  %@AB@%OS/2 Support%@AE@%%@NL@%
  418. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  419. %@NL@%
  420. %@NL@%
  421. %@AB@%Chapter 14%@AE@%%@BO:       be208@%  %@AB@%Building OS/2 Applications%@AE@%%@NL@%
  422. %@NL@%
  423.      14.1%@BO:       be7b1@%  The OS/2 Applications Program Interface%@NL@%
  424.             14.1.1%@BO:       bec33@%    Calling the OS/2 API%@NL@%
  425.             14.1.2%@BO:       bf231@%    Including the OS/2 Header Files%@NL@%
  426.             14.1.3%@BO:       c006c@%    Creating Dual-Mode Programs as Family Applications%@NL@%
  427.      14.2%@BO:       c1470@%  Compile Options for the CL Command%@NL@%
  428.             14.2.1%@BO:       c1726@%    The Link Mode Options (/Lp, /Lr, and /Lc)%@NL@%
  429.             14.2.2%@BO:       c2381@%    Creating Bound Programs Option (/Fb)%@NL@%
  430.             14.2.3%@BO:       c2dcb@%    Library Selection Options (/MT, /ML, /MD, /Zl)%@NL@%
  431.             14.2.4%@BO:       c3cbe@%    Memory-Model Options (/Ax)%@NL@%
  432.      14.3%@BO:       c4599@%  Module-Definition Files and Import Libraries%@NL@%
  433.             14.3.1%@BO:       c53a4@%    Adding a Module-Definition File to the LINK Command%@NL@%
  434.             14.3.2%@BO:       c5818@%    Creating Dynamic-Link Libraries (DLLs)%@NL@%
  435.             14.3.3%@BO:       c5fe4@%    Creating Programs with I/O Privileges%@NL@%
  436.             14.3.4%@BO:       c670a@%    Creating Presentation Manager Applications%@NL@%
  437.             14.3.5%@BO:       c702b@%    Creating Import Libraries with the IMPLIB Utility%@NL@%
  438.      14.4%@BO:       c772b@%  Link Command-Line Options%@NL@%
  439.      14.5%@BO:       c87b2@%  The BIND Utility%@NL@%
  440. %@NL@%
  441. %@AB@%Chapter 15%@AE@%%@BO:       c9373@%  %@AB@%Creating Multithread OS/2 Applications%@AE@%%@NL@%
  442. %@NL@%
  443.      15.1%@BO:       c9735@%  Multithread Programs%@NL@%
  444.             15.1.1%@BO:       c9dc6@%    Library Support%@NL@%
  445.             15.1.2%@BO:       cb9f3@%    Include Files%@NL@%
  446.             15.1.3%@BO:       cbed0@%    C Run-Time Library Functions for Thread Control%@NL@%
  447.      15.2%@BO:       cd17f@%  Sample Multithread C Program%@NL@%
  448.      15.3%@BO:       cf4e2@%  Writing a Multithread Program%@NL@%
  449.      15.4%@BO:       d1b51@%  Compiling and Linking%@NL@%
  450.      15.5%@BO:       d282f@%  Avoiding Problem Areas%@NL@%
  451.      15.6%@BO:       d37c9@%  Using the Protected-Mode CodeView Debugger%@NL@%
  452.             15.6.1%@BO:       d3c94@%    Compiling with the /Zi Option%@NL@%
  453.             15.6.2%@BO:       d3f28@%    Prompt for Thread Number%@NL@%
  454.             15.6.3%@BO:       d4099@%    Thread Commands%@NL@%
  455.             15.6.4%@BO:       d5b8c@%    Screen Groups Used by CodeView%@NL@%
  456. %@NL@%
  457. %@AB@%Chapter 16%@AE@%%@BO:       d5e3d@%  %@AB@%Dynamic Linking with OS/2%@AE@%%@NL@%
  458. %@NL@%
  459.      16.1%@BO:       d61d4@%  Overview of Dynamic Linking%@NL@%
  460.             16.1.1%@BO:       d6650@%    Load-Time and Run-Time Linking%@NL@%
  461.             16.1.2%@BO:       d6b99@%    Application Programs and DLLs%@NL@%
  462.             16.1.3%@BO:       d6f69@%    DLLs and Microsoft C Run-Time Libraries%@NL@%
  463.      16.2%@BO:       d825b@%  Designing and Writing DLLs%@NL@%
  464.             16.2.1%@BO:       d853e@%    Floating-Point Math Requirements%@NL@%
  465.             16.2.2%@BO:       d8f0f@%    Initialization and Termination Requirements%@NL@%
  466.             16.2.3%@BO:       daf4b@%    Making the DLL Re-Entrant%@NL@%
  467.             16.2.4%@BO:       dc9ad@%    Signal Handling%@NL@%
  468.             16.2.5%@BO:       dcb62@%    Using Microsoft C Keywords%@NL@%
  469.             16.2.6%@BO:       dd57b@%    Compile Options for Dynamic-Link Libraries%@NL@%
  470.      16.3%@BO:       de27b@%  Building DLLs with Microsoft C%@NL@%
  471.             16.3.1%@BO:       de508@%    DLLs with Static C Run-Time Library Functions%@NL@%
  472.             16.3.2%@BO:       e0bb2@%    DLLs without C Run-Time Library Functions%@NL@%
  473.             16.3.3%@BO:       e1318@%    Programs and DLLs with a C Run-Time DLL%@NL@%
  474.             16.3.4%@BO:       e3bfc@%    Using CodeView to Debug Dynamic-Link Libraries%@NL@%
  475. %@NL@%
  476. %@AB@%Appendix A%@AE@%%@BO:       e416c@%  %@AB@%Using Exit Codes%@AE@%%@NL@%
  477. %@NL@%
  478.      A.1%@BO:       e4487@%   The exit Function%@NL@%
  479.      A.2%@BO:       e4c25@%   Testing Exit Codes from Command and Batch Files%@NL@%
  480.      A.3%@BO:       e516f@%   Accessing Exit Codes from Other Programs%@NL@%
  481. %@NL@%
  482. %@AB@%Appendix B%@AE@%%@BO:       e5c07@%  %@AB@%Differences between C Versions 5.1 and 6.0%@AE@%%@NL@%
  483. %@NL@%
  484.      B.1%@BO:       e5f2b@%   Modifications for ANSI Compatibility%@NL@%
  485.             B.1.1%@BO:       e604a@%    ANSI-Mandated New Features%@NL@%
  486.             B.1.2%@BO:       e6582@%    Integer Promotion Rules%@NL@%
  487.             B.1.3%@BO:       e69a6@%    Defining NULL as a Pointer%@NL@%
  488.             B.1.4%@BO:       e6aeb@%    Shift Operators%@NL@%
  489.             B.1.5%@BO:       e6e1a@%    Pointers to Typedefs%@NL@%
  490.             B.1.6%@BO:       e7281@%    Identifying Nonstandard Keywords%@NL@%
  491.             B.1.7%@BO:       e76c3@%    Trigraphs%@NL@%
  492.             B.1.8%@BO:       e7a5c@%    ANSI Nonconformance%@NL@%
  493.      B.2%@BO:       e7d0b@%   New Keywords and Functions%@NL@%
  494.             B.2.1%@BO:       e7e33@%    In-Line Assembler%@NL@%
  495.             B.2.2%@BO:       e7fa5@%    Based Pointers and Objects%@NL@%
  496.             B.2.3%@BO:       e8ba2@%    Based Heap Allocation Support%@NL@%
  497.             B.2.4%@BO:       e8ee2@%    Releasing Unused Heap Memory%@NL@%
  498.             B.2.5%@BO:       e9138@%    Making Static Data Available to the Heap%@NL@%
  499.             B.2.6%@BO:       e9224@%    Long Doubles%@NL@%
  500.             B.2.7%@BO:       e9612@%    Long Double Functions%@NL@%
  501.             B.2.8%@BO:       e99c4@%    Model-Independent String and Memory Functions%@NL@%
  502.             B.2.9%@BO:       ea290@%    Mixed-Model Memory Allocation Support%@NL@%
  503.             B.2.10%@BO:       ea4f7@%   The _fastcall Attribute (/Gr Option)%@NL@%
  504.             B.2.11%@BO:       eaef3@%   Drive and Directory Functions%@NL@%
  505.             B.2.12%@BO:       eb1d9@%   Text Output Functions for OS/2%@NL@%
  506.      B.3%@BO:       eb630@%   New Features%@NL@%
  507.             B.3.1%@BO:       eb6d7@%    Strings and Macros%@NL@%
  508.             B.3.2%@BO:       eb7a0@%    CL Options%@NL@%
  509.             B.3.3%@BO:       ec428@%    Tiny Memory Model (.COM Files)%@NL@%
  510.             B.3.4%@BO:       ec60e@%    The Optimize Pragma%@NL@%
  511.             B.3.5%@BO:       ec8b7@%    Nameless Structures and Unions%@NL@%
  512.             B.3.6%@BO:       ecc74@%    Unsized Arrays as the Last Member of a Structure%@NL@%
  513.             B.3.7%@BO:       ecfbb@%    Improved Warnings%@NL@%
  514.             B.3.8%@BO:       ed1ac@%    Macros%@NL@%
  515.             B.3.9%@BO:       ed252@%    Improved Multithread Support in OS/2%@NL@%
  516.             B.3.10%@BO:       ed5ec@%   Pipe Support in OS/2%@NL@%
  517.      B.4%@BO:       ed84a@%   Differences in Code Generation%@NL@%
  518.             B.4.1%@BO:       ed956@%    Speed and Space Improvements%@NL@%
  519.             B.4.2%@BO:       ed9f0@%    Code Quality%@NL@%
  520.             B.4.3%@BO:       edb8b@%    Floating-Point Code Generation%@NL@%
  521.             B.4.4%@BO:       ede82@%    Intrinsic Functions%@NL@%
  522.      B.5%@BO:       ee528@%   Changes and Deletions%@NL@%
  523.             B.5.1%@BO:       ee5f9@%    Deleted Features%@NL@%
  524.             B.5.2%@BO:       ee77b@%    Evaluation of Real Expressions%@NL@%
  525.             B.5.3%@BO:       ee929@%    Default Optimizations%@NL@%
  526.             B.5.4%@BO:       eeadf@%    Sign Extension of char Arguments%@NL@%
  527.             B.5.5%@BO:       eec98@%    Conditional Compilation and Signed Values%@NL@%
  528.             B.5.6%@BO:       eee9b@%    The const and volatile Qualifiers%@NL@%
  529.             B.5.7%@BO:       ef152@%    Memory Allocation%@NL@%
  530.             B.5.8%@BO:       ef2a5@%    Memory Used by Command-Line Arguments%@NL@%
  531.             B.5.9%@BO:       ef40f@%    Format Specifiers in printf%@NL@%
  532.             B.5.10%@BO:       ef859@%   Functions that Return Float Values%@NL@%
  533. %@NL@%
  534. %@AB@%Appendix C%@AE@%%@BO:       efa07@%  %@AB@%Implementation-Defined Behavior%@AE@%%@NL@%
  535. %@NL@%
  536.      C.1%@BO:       efe6d@%   Translation%@NL@%
  537.             C.1.1%@BO:       efebc@%    Diagnostics%@NL@%
  538.      C.2%@BO:       f017d@%   Environment%@NL@%
  539.             C.2.1%@BO:       f01cc@%    Arguments to main%@NL@%
  540.             C.2.2%@BO:       f0890@%    Interactive Devices%@NL@%
  541.      C.3%@BO:       f098e@%   Identifiers%@NL@%
  542.             C.3.1%@BO:       f09dd@%    Significant Characters without External Linkage%@NL@%
  543.             C.3.2%@BO:       f0b7a@%    Significant Characters with External Linkage%@NL@%
  544.             C.3.3%@BO:       f0d79@%    Upper- and Lowercase%@NL@%
  545.      C.4%@BO:       f11dd@%   Characters%@NL@%
  546.             C.4.1%@BO:       f122b@%    The ASCII Character Set%@NL@%
  547.             C.4.2%@BO:       f151c@%    Multibyte Characters%@NL@%
  548.             C.4.3%@BO:       f168f@%    Bits per Character%@NL@%
  549.             C.4.4%@BO:       f17cf@%    Character Sets%@NL@%
  550.             C.4.5%@BO:       f1bf4@%    Unrepresented Character Constants%@NL@%
  551.             C.4.6%@BO:       f1d93@%    Wide Characters%@NL@%
  552.             C.4.7%@BO:       f1f0d@%    Converting Multibyte Characters%@NL@%
  553.             C.4.8%@BO:       f2060@%    Range of char Values%@NL@%
  554.      C.5%@BO:       f227f@%   Integers%@NL@%
  555.             C.5.1%@BO:       f22cb@%    Range of Integer Values%@NL@%
  556.             C.5.2%@BO:       f2659@%    Demotion of Integers%@NL@%
  557.             C.5.3%@BO:       f2a1d@%    Signed Bitwise Operations%@NL@%
  558.             C.5.4%@BO:       f2c39@%    Remainders%@NL@%
  559.             C.5.5%@BO:       f2da8@%    Right Shifts%@NL@%
  560.      C.6%@BO:       f3130@%   Floating-Point Math%@NL@%
  561.             C.6.1%@BO:       f3187@%    Values%@NL@%
  562.             C.6.2%@BO:       f34ae@%    Casting Integers to Floating-Point Values%@NL@%
  563.             C.6.3%@BO:       f37ce@%    Truncation of Floating-Point Values%@NL@%
  564.      C.7%@BO:       f396c@%   Arrays and Pointers%@NL@%
  565.             C.7.1%@BO:       f39c3@%    Largest Array Size%@NL@%
  566.             C.7.2%@BO:       f3c0e@%    Casting Pointers%@NL@%
  567.             C.7.3%@BO:       f4018@%    Pointer Subtraction%@NL@%
  568.      C.8%@BO:       f42d8@%   Registers%@NL@%
  569.             C.8.1%@BO:       f4325@%    Availability of Registers%@NL@%
  570.      C.9%@BO:       f44b9@%   Structures, Unions, Enumerations, and Bit Fields%@NL@%
  571.             C.9.1%@BO:       f452d@%    Improper Access to a Union%@NL@%
  572.             C.9.2%@BO:       f47e3@%    Sign of Bit Fields%@NL@%
  573.             C.9.3%@BO:       f4925@%    Storage of Bit Fields%@NL@%
  574.             C.9.4%@BO:       f4cba@%    Alignment of Bit Fields%@NL@%
  575.             C.9.5%@BO:       f4f59@%    The enum Type%@NL@%
  576.      C.10%@BO:       f5071@%  Qualifiers%@NL@%
  577.             C.10.1%@BO:       f50c0@%   Access to Volatile Objects%@NL@%
  578.      C.11%@BO:       f51dc@%  Declarators%@NL@%
  579.             C.11.1%@BO:       f522c@%   Maximum Number%@NL@%
  580.      C.12%@BO:       f537a@%  Statements%@NL@%
  581.             C.12.1%@BO:       f53c9@%   Limits on Switch Statements%@NL@%
  582.      C.13%@BO:       f552c@%  Preprocessing Directives%@NL@%
  583.             C.13.1%@BO:       f5589@%   Character Constants and Conditional Inclusion%@NL@%
  584.             C.13.2%@BO:       f57dc@%   Including Bracketed File Names%@NL@%
  585.             C.13.3%@BO:       f5bc9@%   Including Quoted File Names%@NL@%
  586.             C.13.4%@BO:       f5eb7@%   Character Sequences%@NL@%
  587.             C.13.5%@BO:       f6113@%   Pragmas%@NL@%
  588.             C.13.6%@BO:       f648b@%   Default Date and Time%@NL@%
  589.      C.14%@BO:       f6604@%  Library Functions%@NL@%
  590.             C.14.1%@BO:       f665a@%   NULL Macro%@NL@%
  591.             C.14.2%@BO:       f6761@%   Diagnostic Printed by the assert Function%@NL@%
  592.             C.14.3%@BO:       f6a50@%   Character Testing%@NL@%
  593.             C.14.4%@BO:       f6ea9@%   Domain Errors%@NL@%
  594.             C.14.5%@BO:       f6fb1@%   Underflow of Floating-Point Values%@NL@%
  595.             C.14.6%@BO:       f7176@%   The fmod Function%@NL@%
  596.             C.14.7%@BO:       f72cd@%   The signal Function%@NL@%
  597.             C.14.8%@BO:       f7c08@%   Default Signals%@NL@%
  598.             C.14.9%@BO:       f7d6e@%   The SIGILL Signal%@NL@%
  599.             C.14.10%@BO:       f7efd@%  Terminating Newline Characters%@NL@%
  600.             C.14.11%@BO:       f804e@%  Blank Lines%@NL@%
  601.             C.14.12%@BO:       f8174@%  Null Characters%@NL@%
  602.             C.14.13%@BO:       f829c@%  File Position in Append Mode%@NL@%
  603.             C.14.14%@BO:       f841d@%  Truncation of Text Files%@NL@%
  604.             C.14.15%@BO:       f855b@%  File Buffering%@NL@%
  605.             C.14.16%@BO:       f86d2@%  Zero-Length Files%@NL@%
  606.             C.14.17%@BO:       f87b4@%  File Names%@NL@%
  607.             C.14.18%@BO:       f89f5@%  File Access Limits%@NL@%
  608.             C.14.19%@BO:       f8ae9@%  Deleting Open Files%@NL@%
  609.             C.14.20%@BO:       f8bf5@%  Renaming with a Name that Exists%@NL@%
  610.             C.14.21%@BO:       f8d68@%  Printing Pointer Values%@NL@%
  611.             C.14.22%@BO:       f9000@%  Reading Pointer Values%@NL@%
  612.             C.14.23%@BO:       f9167@%  Reading Ranges%@NL@%
  613.             C.14.24%@BO:       f9361@%  File Position Errors%@NL@%
  614.             C.14.25%@BO:       f9542@%  Messages Generated by the perror Function%@NL@%
  615.             C.14.26%@BO:       f991d@%  Allocating Zero Memory%@NL@%
  616.             C.14.27%@BO:       f9ad6@%  The abort Function%@NL@%
  617.             C.14.28%@BO:       f9c2a@%  The atexit Function%@NL@%
  618.             C.14.29%@BO:       f9d9c@%  Environment Names%@NL@%
  619.             C.14.30%@BO:       fa192@%  The system Function%@NL@%
  620.             C.14.31%@BO:       fa403@%  The strerror Function%@NL@%
  621.             C.14.32%@BO:       fa814@%  The Time Zone%@NL@%
  622.             C.14.33%@BO:       fa923@%  The clock Function%@NL@%
  623.  
  624. %@AB@%Index%@AE@%%@BO:       faa6e@%
  625.  
  626.  
  627. %@NL@%
  628. %@NL@%
  629. %@CR:C6A-Intro   @%%@1@%%@AB@%Introduction%@AE@%%@EH@%%@NL@%
  630. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  631. %@NL@%
  632. %@AI@%Advanced Programming Techniques%@AE@% describes how to get the most out of the
  633. Microsoft(R) C Professional Development System with its new integrated
  634. development environment─the Microsoft Programmer's WorkBench─and
  635. source-level debugging tool─the CodeView(R) debugger.  %@NL@%
  636. %@NL@%
  637. In this manual, you will see how all the components of the Microsoft C
  638. Professional Development System work together to provide you with the most
  639. powerful development environment available. A key element in the power of
  640. the Professional Development System is your ability to customize it to suit
  641. your individual needs as a programmer.  %@NL@%
  642. %@NL@%
  643. Because this book is arranged by topic, it answers questions about using
  644. Microsoft C version 6.0, rather than providing lists of options. If you have
  645. specific questions about menu items in the CodeView debugger, the
  646. Programmer's WorkBench, or any of the command-line utilities included in the
  647. Professional Development System, you can use the Microsoft C Advisor
  648. (on-line help) or the %@AI@%C Reference%@AE@% manual. %@AI@%  %@AE@%%@NL@%
  649. %@NL@%
  650. %@AI@%Advanced Programming Techniques%@AE@% shows you how tools and utilities all fit
  651. together.  %@NL@%
  652. %@NL@%
  653. %@NL@%
  654. %@2@%%@CR:C6A00010001 @%%@AB@%Scope of This Book%@AE@%%@EH@%%@NL@%
  655. %@NL@%
  656. %@AI@%Advanced Programming Techniques%@AE@% is divided into four parts. Part 1,
  657. "Improving Program Performance," helps you write more efficient programs. It
  658. provides specific information about optimizing─when and why to use various
  659. optimizing options. It also explains new memory management options and when
  660. to use them. For example, Chapter 3 describes the in-line assembler, a new
  661. feature that lets you mix assembly language with your C source code.  %@NL@%
  662. %@NL@%
  663. Part 2, "Improving Programmer Productivity," will help you perform
  664. programming tasks more quickly and efficiently. Chapter 8 explains the
  665. different ways you can customize the new Programmer's WorkBench (PWB)─an
  666. editor and integrated development environment that allows you to  %@NL@%
  667. %@NL@%
  668. %@NL@%
  669.   ■   Create new programs%@NL@%
  670. %@NL@%
  671.   ■   Modify existing programs%@NL@%
  672. %@NL@%
  673.   ■   Browse source files%@NL@%
  674. %@NL@%
  675.   ■   Obtain help about PWB, the C language, and the C run-time libraries%@NL@%
  676. %@NL@%
  677.   ■   Set program build lists%@NL@%
  678. %@NL@%
  679.   ■   Build programs%@NL@%
  680. %@NL@%
  681.   ■   Debug programs with the CodeView debugger%@NL@%
  682. %@NL@%
  683. %@NL@%
  684. Chapter 8 also describes how to change PWB behavior to suit your programming
  685. style by making keyboard assignments, recording or writing macros, and
  686. writing C extensions.  %@NL@%
  687. %@NL@%
  688. Also in Part 2 is a chapter about the Microsoft Program Maintenance Utility,
  689. NMAKE. NMAKE is a new program maintenance facility that allows you to use
  690. program lists as input, which provides extra flexibility in your program
  691. build process. It is a superset of the Microsoft XENIX(R) MAKE utility and
  692. is substantially more powerful than previous versions of MAKE.  %@NL@%
  693. %@NL@%
  694. Chapter 9 in Part 2 describes the CodeView debugger, which is even more
  695. powerful than in previous releases. With CodeView version 3.0, you get many
  696. new features, including the ability to record a debugging session, then play
  697. it back (history and dynamic replay).  %@NL@%
  698. %@NL@%
  699. Part 3, "Special Environments," describes new graphics capabilities. It also
  700. shows how to program in mixed languages and offers tips to make your
  701. programs more portable. Microsoft C helps you create graphics applications
  702. easily. The Microsoft C run-time libraries contain graphics functions for
  703. low-level graphics operations, such as drawing lines, rectangles, and
  704. circles. The libraries also contain functions for creating presentation
  705. graphics, such as pie charts and bar charts.  %@NL@%
  706. %@NL@%
  707. Part 4, "OS/2 Support," describes how the Professional Development System
  708. helps you build OS/2 applications. The three chapters in Part 4 provide
  709. information about dual-mode applications, creating multithread applications,
  710. and creating dynamic-link libraries.  %@NL@%
  711. %@NL@%
  712. A postage-paid documentation feedback card is at the end of this manual.
  713. After you have had a chance to become familiar with Microsoft C 6.0 and its
  714. documentation, please give us your opinion. Your ideas will help us as we
  715. develop future documentation. Also at the end of this book is a Product
  716. Assistance Request form. If you need to call Microsoft for assistance, use
  717. this form first to compile and organize pertinent information.  %@NL@%
  718. %@NL@%
  719. %@NL@%
  720. %@2@%%@CR:C6A00010002 @%%@AB@%Document Conventions%@AE@%%@EH@%%@NL@%
  721. %@NL@%
  722. ────────────────────────────────────────────────────────────────────────────%@NL@%
  723. NOTE
  724.  
  725. %@AI@%The pages that follow use the term "OS/2" to refer to the OS/2
  726. %@AI@%systems─Microsoft Operating System/2 (MS%@AI@%(R)%@AE@%%@AI@% OS/2) and IBM%@AE@%%@AI@%(R) %@AE@%%@AI@%OS/2.
  727. %@AI@%Similarly, the term "DOS" refers to both the MS-DOS%@AE@%%@AI@%(R)%@AE@%%@AI@% and IBM Personal
  728. %@AI@%Computer DOS operating systems. The name of a specific operating system is
  729. %@AI@%used when it is necessary to note features that are unique to the system.%@AE@%%@AE@%%@NL@%
  730.  
  731.  
  732. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  733. %@NL@%
  734. %@AB@%Example%@AE@%                           %@AB@%Description%@AE@%
  735. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  736. STDIO.H                           Uppercase letters indicate file names, 
  737.                                   segment names, registers, and terms used
  738.                                   at the DOS- or OS/2-command level.
  739.  
  740. %@AB@%_cdecl%@AE@%                            Boldface letters indicate C keywords, 
  741.                                   operators, language-specific characters,
  742.                                   and library functions, as well as OS/2 
  743.                                   functions. Within discussions of syntax,
  744.                                   bold type indicates that the text must 
  745.                                   be entered exactly as shown.
  746.  
  747. %@AI@%expression%@AE@%                        Words in italics indicate placeholders 
  748.                                   for information you must supply, such as
  749.                                   a file name. Italics are also 
  750.                                   occasionally used for emphasis in the 
  751.                                   text.
  752.  
  753. «%@AI@%option%@AE@%»                          Items inside double square brackets are 
  754.                                   optional. 
  755.  
  756. %@AB@%#pragma pack%@AE@% {%@AB@%1%@AE@%|%@AB@%2%@AE@%}                Braces and a vertical bar indicate a 
  757.                                   choice among two or more items. You must
  758.                                   choose one of these items unless double 
  759.                                   square brackets surround the braces.
  760.  
  761. %@AS@%CL A.C B.C C.OBJ%@AE@%                  This font is used for examples, user 
  762.                                   input, program output, and error 
  763.                                   messages in text.
  764.  
  765. %@AB@%CL%@AE@% %@AI@%options%@AE@% «%@AI@% files%@AE@%...»            A horizontal ellipsis following an item 
  766.                                   indicates that more items having the 
  767.                                   same form may follow.
  768.  
  769. %@AS@%while%@AE@%(   )                        A vertical ellipsis tells you that part 
  770. {                                 of the example program has been 
  771.    .                              intentionally omitted.
  772.    .                              
  773.    .                              
  774. }                                 
  775.  
  776. CTRL+ENTER                        Small capital letters are used for the 
  777.                                   names of keys on the keyboard. When you 
  778.                                   see a plus sign (+) between two key 
  779.                                   names, you should hold down the first 
  780.                                   key while pressing the second.
  781.  
  782.                                   The carriage-return key (sometimes 
  783.                                   appearing as a bent arrow on the 
  784.                                   keyboard) is called ENTER.
  785.  
  786.                                   The cursor-movement keys (sometimes 
  787.                                   called direction keys) are called the 
  788.                                   ARROW keys. Individual keys are referred
  789.                                   to by their direction (LEFT, UP) or by 
  790.                                   the name on the key (PGUP).
  791.  
  792. "argument"                        Quotation marks enclose a new term the 
  793.                                   first time it is defined in text.
  794.  
  795. Enhanced Graphics Adapter (EGA)   The first time an acronym is used, it is
  796.                                   often spelled out.
  797.  
  798. %@NL@%
  799. %@NL@%
  800. %@NL@%
  801. %@NL@%
  802. %@NL@%
  803. %@CR:C6A-Part 01 @%%@1@%%@AB@%PART I  Improving Program Performance%@AE@%%@EH@%%@NL@%
  804. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  805. %@NL@%
  806. The Microsoft C Professional Development System helps you create the
  807. fastest, smallest applications using its sophisticated optimizer and
  808. enhanced memory management capabilities.  %@NL@%
  809. %@NL@%
  810. Chapter 1 tells when to use certain optimizations and describes how
  811. Microsoft C generates code that is efficient in execution speed and size.
  812. Chapter 2 explains the sophisticated tools Microsoft C gives you to allocate
  813. and manage program memory, including the new %@AB@%_based%@AE@% type. For cases where
  814. your program requires localized optimization, you can use the in-line
  815. assembler, described in Chapter 3, to introduce the tightest possible code.
  816. If your application requires floating-point math computations, you will find
  817. Chapter 4 helpful in explaining the options in the Microsoft C math
  818. packages; it explains which floating-point options yield the fastest,
  819. smallest, and most flexible code.  %@NL@%
  820. %@NL@%
  821. %@NL@%
  822. %@NL@%
  823. %@NL@%
  824. %@NL@%
  825. %@NL@%
  826. %@CR:C6A00010001 @%%@1@%%@AB@%Chapter 1  Optimizing C Programs%@AE@%%@EH@%%@NL@%
  827. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  828. %@NL@%
  829. The Microsoft C compiler translates C source statements into
  830. machineexecutable instructions. In addition, the compiler rewrites or
  831. "optimizes"  parts of your program to make it more efficient in ways that
  832. are not apparent at the source level.  %@NL@%
  833. %@NL@%
  834. The compiler performs three general types of optimization:  %@NL@%
  835. %@NL@%
  836. %@NL@%
  837.   1.  It modifies or moves sections of code so that fewer instructions are
  838.       used, or so that the instructions used make more efficient use of the
  839.       processor.%@NL@%
  840. %@NL@%
  841.   2.  It moves code and combines operations to maximize use of registers
  842.       because operations on data stored in processor registers are far
  843.       faster than the same operations on data stored in memory.%@NL@%
  844. %@NL@%
  845.   3.  It eliminates sections of code that are redundant or unused.%@NL@%
  846. %@NL@%
  847. %@NL@%
  848. This chapter explains the various ways you can control how the Microsoft C
  849. compiler optimizes your code.  %@NL@%
  850. %@NL@%
  851. %@NL@%
  852. %@2@%%@CR:C6A00010002 @%%@AB@%1.1  Controlling Optimization from the Programmer's WorkBench%@AE@%%@EH@%%@NL@%
  853. %@NL@%
  854. The Programmer's WorkBench (PWB) is an integrated development environment
  855. for editing, building, and debugging applications written in Microsoft C.
  856. For more information on the PWB, see %@AI@%Installing and Using the Microsoft C
  857. %@AI@%Professional Development System%@AE@%.  %@NL@%
  858. %@NL@%
  859. There are two ways to compile from inside the Programmer's WorkBench:  %@NL@%
  860. %@NL@%
  861. %@NL@%
  862.   1.  Debug compile. In a default debug compile, the compiler performs no
  863.       optimizations at all.%@NL@%
  864. %@NL@%
  865.   2.  Release compile. In a default release compile, the compiler performs
  866.       most optimizations.%@NL@%
  867. %@NL@%
  868. %@NL@%
  869. By modifying the settings in C Global Build Options, C Debug Build Options,
  870. and C Release Build Options (on the Options menu), you can fine-tune
  871. optimization by individually enabling or disabling any of the optimizations
  872. the compiler performs.  %@NL@%
  873. %@NL@%
  874. The optimizations in each of the Build Options dialog boxes correspond to a
  875. command-line option to CL. (In fact, the PWB constructs a command line from
  876. your input and passes it to CL.)  %@NL@%
  877. %@NL@%
  878. ────────────────────────────────────────────────────────────────────────────%@NL@%
  879. NOTE
  880.  
  881. %@AI@%In this chapter, optimization options are discussed in terms of the effect
  882. %@AI@%of the optimization, the command-line option to invoke the optimization, and
  883. %@AI@%pragmas that control the optimization. All of these optimizations can be
  884. %@AI@%controlled at the compilation-unit (file) level using the Build Options
  885. %@AI@%dialog boxes.%@AE@%%@NL@%
  886. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  887. %@NL@%
  888. %@NL@%
  889. %@2@%%@CR:C6A00010003 @%%@AB@%1.2  Controlling Optimization from the Command Line%@AE@%%@EH@%%@NL@%
  890. %@NL@%
  891. Controlling optimization from the command line requires that you determine
  892. which optimizations you need for your application. You then specify those
  893. optimizations using command-line options that begin with /O (and in some
  894. cases /G).  %@NL@%
  895. %@NL@%
  896. If there is any conflict between options, the compiler uses the last option
  897. specified on the command line. The command line  %@NL@%
  898. %@NL@%
  899. %@AS@%  CL /Oa /Ol /Ot TEST.C%@AE@%%@NL@%
  900. %@NL@%
  901. compiles the program TEST.C. It specifies that the compiler can  %@NL@%
  902. %@NL@%
  903. %@NL@%
  904.   ■   Optimize on the assumption that you are doing no aliasing (/Oa)%@NL@%
  905. %@NL@%
  906.   ■   Perform loop optimization (/Ol)%@NL@%
  907. %@NL@%
  908.   ■   Perform other general speed-enhancing optimizations (/Ot)%@NL@%
  909. %@NL@%
  910. %@NL@%
  911. The preceding command line can also be written  %@NL@%
  912. %@NL@%
  913. %@AS@%  CL /Oalt TEST.C%@AE@%%@NL@%
  914. %@NL@%
  915. %@NL@%
  916. %@2@%%@CR:C6A00010004 @%%@AB@%1.3  Controlling Optimization with Pragmas%@AE@%%@EH@%%@NL@%
  917. %@NL@%
  918. Occasionally you will need to exercise a fine level of control over compiler
  919. optimizations. Command-line options allow you to control optimization over
  920. an entire compilation unit (file). In addition, Microsoft C supports several
  921. pragmas that allow you to exercise such control on a per-function basis.  %@NL@%
  922. %@NL@%
  923. The pragmas that control optimization are described in this chapter under
  924. the type of optimization they affect.  %@NL@%
  925. %@NL@%
  926. %@AU@% The optimize pragma is new to version 6.0.%@AE@%  %@NL@%
  927. %@NL@%
  928. In version 6.0, you can control each of the following optimization
  929. parameters on a function-by-function basis using the %@AB@%optimize%@AE@% pragma:  %@NL@%
  930. %@NL@%
  931. %@NL@%
  932.   ■   Behavior of code with respect to aliasing (%@AB@%a%@AE@% and %@AB@%w%@AE@%)%@NL@%
  933. %@NL@%
  934.   ■   Reduction of local common subexpressions (%@AB@%c%@AE@%)%@NL@%
  935. %@NL@%
  936.   ■   Reduction of global common subexpressions (%@AB@%g%@AE@%)%@NL@%
  937. %@NL@%
  938.   ■   Global register allocation (%@AB@%e%@AE@%)%@NL@%
  939. %@NL@%
  940.   ■   Loop optimization (%@AB@%l%@AE@%)%@NL@%
  941. %@NL@%
  942.   ■   Aggressiveness of optimizations (%@AB@%z%@AE@%)%@NL@%
  943. %@NL@%
  944.   ■   Disabling of unsafe optimizations (%@AB@%n%@AE@%)%@NL@%
  945. %@NL@%
  946.   ■   Achieving consistent floating-point results (%@AB@%p%@AE@%)%@NL@%
  947. %@NL@%
  948.   ■   Optimizing for smaller code size or for faster execution speed (%@AB@%t%@AE@%)%@NL@%
  949. %@NL@%
  950. %@NL@%
  951. Any optimization or combination of options can be enabled or disabled using
  952. the %@AB@%optimize%@AE@% pragma. For example, if you have one function that uses aliases
  953. heavily, you need to inhibit optimizations that could cause problems with
  954. aliases. You do not, however, want to inhibit these optimizations for code
  955. that does not do aliasing. To do this, use the %@AB@%optimize %@AE@%pragma as follows:  %@NL@%
  956. %@NL@%
  957. %@AS@%  /* Function(s) that do not do aliasing. */
  958. %@AS@%  .
  959. %@AS@%  .
  960. %@AS@%  .
  961. %@AS@%  #pragma optimize( "a", off )
  962. %@AS@%  /* Function(s) that do aliasing. */
  963. %@AS@%  .
  964. %@AS@%  .
  965. %@AS@%  .
  966. %@AS@%  #pragma optimize( "a", on )
  967. %@AS@%  /* More function(s) that do not do aliasing. */%@AE@%%@NL@%
  968. %@NL@%
  969. The parameters to the %@AB@%optimize %@AE@%pragma can be combined in a string to enable
  970. or disable multiple options at once. For example,  %@NL@%
  971. %@NL@%
  972. %@AS@%  #pragma optimize( "lge", off )%@AE@%%@NL@%
  973. %@NL@%
  974. disables loop optimization, global common subexpression optimization, and
  975. global register allocation.  %@NL@%
  976. %@NL@%
  977. %@NL@%
  978. %@2@%%@CR:C6A00010005 @%%@AB@%1.4  Default Optimization%@AE@%%@EH@%%@NL@%
  979. %@NL@%
  980. Many optimizations are not explicitly disabled by any command-line option
  981. except /Od (disable optimizations). These optimizations are small in scope
  982. and are almost always helpful. They include  %@NL@%
  983. %@NL@%
  984. %@NL@%
  985.   ■   Short range common subexpression elimination%@NL@%
  986. %@NL@%
  987.   ■   Dead-store elimination%@NL@%
  988. %@NL@%
  989.   ■   Constant propagation%@NL@%
  990. %@NL@%
  991. %@NL@%
  992. %@NL@%
  993. %@3@%%@CR:C6A00010006 @%%@AB@%1.4.1  Common Subexpression Elimination%@AE@%%@EH@%%@NL@%
  994. %@NL@%
  995. In common subexpression elimination, the compiler finds code containing
  996. repeated subexpressions and produces modified code in which the
  997. subexpressions are evaluated only once. Subexpression elimination is usually
  998. done with temporary variables as shown in the following example:  %@NL@%
  999. %@NL@%
  1000. %@AS@%  a = b + c * d;
  1001. %@AS@%  x = c * d / y;%@AE@%%@NL@%
  1002. %@NL@%
  1003. The preceding two lines contain the common subexpression %@AS@% c * d%@AE@%. This code
  1004. can be modified to evaluate %@AS@% c * d %@AE@% only once; the result is placed in a
  1005. temporary variable (usually a register):  %@NL@%
  1006. %@NL@%
  1007. %@AS@%  tmp = c * d;
  1008. %@AS@%  a = b + tmp;
  1009. %@AS@%  x = tmp / y;%@AE@%%@NL@%
  1010. %@NL@%
  1011. %@NL@%
  1012. %@3@%%@CR:C6A00010007 @%%@AB@%1.4.2  Dead-Store Elimination%@AE@%%@EH@%%@NL@%
  1013. %@NL@%
  1014. Dead-store elimination is an extension of common subexpression elimination.
  1015. Variables that contain the same value in a short piece of code can be
  1016. combined into a single temporary variable.  %@NL@%
  1017. %@NL@%
  1018. In the following code fragment, the compiler detects that the expression %@AS@%
  1019. %@AS@%func( x ) %@AE@% is equivalent to %@AS@% func( a + b )%@AE@%:  %@NL@%
  1020. %@NL@%
  1021. %@AS@%  x = a + b;
  1022. %@AS@%  x = func( x );%@AE@%%@NL@%
  1023. %@NL@%
  1024. Thus, the compiler can rewrite the code as follows:  %@NL@%
  1025. %@NL@%
  1026. %@AS@%  x = func( a + b);%@AE@%%@NL@%
  1027. %@NL@%
  1028. %@NL@%
  1029. %@3@%%@CR:C6A00010008 @%%@AB@%1.4.3  Constant Propagation%@AE@%%@EH@%%@NL@%
  1030. %@NL@%
  1031. When doing constant propagation, the compiler analyzes variable assignments
  1032. and determines if they can be changed to constant assignments. In the
  1033. following example, the variable %@AS@% i %@AE@% must have a value of %@AS@% 7 %@AE@% when it is
  1034. assigned to %@AS@% j%@AE@%:  %@NL@%
  1035. %@NL@%
  1036. %@AS@%  i = 7;
  1037. %@AS@%  j = i;%@AE@%%@NL@%
  1038. %@NL@%
  1039. Instead of assigning %@AS@% i %@AE@% to %@AS@% j%@AE@%, the constant %@AS@% 7 %@AE@% can be assigned to %@AS@% j%@AE@%:  %@NL@%
  1040. %@NL@%
  1041. %@AS@%  i = 7;
  1042. %@AS@%  j = 7;%@AE@%%@NL@%
  1043. %@NL@%
  1044. While you could make any of these changes in the source file, doing so might
  1045. reduce the readability of the program. In many cases, optimizations not only
  1046. increase the efficiency of the program but allow you to write more readable
  1047. code without any actual efficiency loss.  %@NL@%
  1048. %@NL@%
  1049. %@AU@% Remove optimization before using a symbolic debugger.%@AE@%  %@NL@%
  1050. %@NL@%
  1051. In some cases, you might want to disable even the default optimizations.
  1052. Because optimizations may rearrange code in the object file, it can become
  1053. difficult to recognize parts of your code during debugging. It is usually
  1054. best to remove all optimization before using a symbolic debugger. You can
  1055. remove all optimization with the /Od (disable optimizations) option.  %@NL@%
  1056. %@NL@%
  1057. You can disable all optimizations for a function by including the statement %@AS@%
  1058. %@AS@%#pragma optimize( "", off )%@AE@%. To restore optimization to its former state,
  1059. use the statement %@AS@% #pragma optimize( "", on )%@AE@%.  %@NL@%
  1060. %@NL@%
  1061. %@NL@%
  1062. %@2@%%@CR:C6A00010009 @%%@AB@%1.5  Customizing Your Optimizations%@AE@%%@EH@%%@NL@%
  1063. %@NL@%
  1064. The default optimizations are sufficient for many applications, but you may
  1065. want to tune your programs according to criteria not known to the compiler.
  1066. The optimization options offer you a way of providing the compiler specific
  1067. goals for optimizing your code.  %@NL@%
  1068. %@NL@%
  1069. %@NL@%
  1070. %@3@%%@CR:C6A00010010 @%%@AB@%1.5.1  Choosing Speed or Size (/Ot and /Os)%@AE@%%@EH@%%@NL@%
  1071. %@NL@%
  1072. In addition to the default optimizations, the Microsoft C compiler also
  1073. automatically uses the /Ot option, which optimizes for speed. The /Ot option
  1074. enables optimizations that increase speed but may also increase size. If you
  1075. would rather optimize for program size, use the /Os option. The /Os option
  1076. enables optimizations that decrease program size but may also decrease
  1077. program speed.  %@NL@%
  1078. %@NL@%
  1079. To optimize for speed or size on a per-function basis, use the %@AB@%optimize
  1080. %@AB@%%@AE@%pragma with the %@AB@%t %@AE@%option. The on setting instructs the compiler to optimize
  1081. for speed; the off setting instructs the compiler to optimize for
  1082. compactness of code. For example,  %@NL@%
  1083. %@NL@%
  1084. %@AS@%  #pragma optimize( "t", off )    /* Optimize for smallest 
  1085. %@AS@%                                    code. */
  1086. %@AS@%  .
  1087. %@AS@%  .
  1088. %@AS@%  .
  1089. %@AS@%  #pragma optimize( "t", on )     /* Optimize for fastest 
  1090. %@AS@%                                    code. */%@AE@%%@NL@%
  1091. %@NL@%
  1092. %@NL@%
  1093. %@3@%%@CR:C6A00010011 @%%@AB@%1.5.2  Generating Intrinsic Functions (/Oi)%@AE@%%@EH@%%@NL@%
  1094. %@NL@%
  1095. In place of some normal function calls, the C compiler can insert "intrinsic
  1096. functions," which operate more quickly. Every time a function is called, a
  1097. set of instructions must be executed to store parameters and to create space
  1098. for local variables. When the function returns, more code must be executed
  1099. to release space used by local variables and parameters and to return values
  1100. to the calling routine. These instructions take time to execute. In the
  1101. context of an average-sized function, the additional code is minimal, but if
  1102. the function is only a line or two, the additional code can comprise almost
  1103. half of the function's compiled code.  %@NL@%
  1104. %@NL@%
  1105. One way to avoid this type of code expansion is to avoid such short
  1106. functions, especially in often-used sections of code where speed is
  1107. critical. But many library functions contain only a line or two of code. The
  1108. compiler provides two forms of certain library functions. One form is a
  1109. standard C function, which requires the overhead of a function call. The
  1110. other form is a set of instructions that  %@NL@%
  1111. %@NL@%
  1112. performs the same action as the function without issuing a function call.
  1113. This second form is called an intrinsic function. Intrinsic functions are
  1114. always faster than their function-call equivalents and can provide
  1115. significant optimizations at the object-code level.  %@NL@%
  1116. %@NL@%
  1117. For example, the function %@AB@%strcpy%@AE@% might be written as follows:  %@NL@%
  1118. %@NL@%
  1119. %@AS@%  int strcpy(char * dest, char * source)
  1120. %@AS@%  {
  1121. %@AS@%      while( *dest++ = *source++ );
  1122. %@AS@%  }%@AE@%%@NL@%
  1123. %@NL@%
  1124. The compiler contains an intrinsic form of %@AB@%strcpy%@AE@%. If you instruct the
  1125. compiler to generate intrinsic functions, any call to %@AB@%strcpy%@AE@% will be
  1126. replaced with this intrin-sic form.  %@NL@%
  1127. %@NL@%
  1128. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1129. NOTE
  1130.  
  1131. %@AI@%While the example above is written in C for clarity, most of the library
  1132. %@AI@%functions use assembly language to take full advantage of the 80x86
  1133. %@AI@%instruction set. Intrinsic functions are not simply library functions
  1134. %@AI@%defined as macros. %@AE@%%@NL@%
  1135. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1136. %@NL@%
  1137. Compiling with the /Oi option causes the compiler to use the intrinsic forms
  1138. of the following functions:  %@NL@%
  1139. %@NL@%
  1140. %@AB@%abs             labs            memset          strcat%@AE@%
  1141. %@AB@%_disable        lrotl           outp            strcmp%@AE@%
  1142. %@AB@%_enable         lrotr           outpw           strcpy%@AE@%
  1143. %@AB@%fabs            memcmp          rotl            strlen%@AE@%
  1144. %@AB@%inp             memcpy          rotr            strset%@AE@%
  1145. %@AB@%inpw            
  1146.  
  1147. While the following floating-point functions do not have true intrinsic
  1148. forms, they do have versions that pass arguments directly to the
  1149. floating-point chip instead of pushing them on the normal argument stack:  %@NL@%
  1150. %@NL@%
  1151. %@AB@%acos            fmod            acosl           fmodl%@AE@%
  1152. %@AB@%asin            log             asinl           logl%@AE@%
  1153. %@AB@%atan            log10           atanl           log10l%@AE@%
  1154. %@AB@%atan2           pow             atan2l          powl%@AE@%
  1155. %@AB@%ceil            sin             ceill           sinl%@AE@%
  1156. %@AB@%cos             sinh            cosl            sinhl%@AE@%
  1157. %@AB@%cosh            sqrt            coshl           sqrtl%@AE@%
  1158. %@AB@%exp             tan             expl            tanl%@AE@%
  1159. %@AB@%floor           tanh            floorl          tanhl%@AE@%
  1160.  
  1161. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1162. %@AU@%WARNING%@AE@%%@NL@%
  1163. %@NL@%
  1164. The compiler performs optimizations assuming math intrinsics have no side
  1165. effects. This assumption is true except if you have written your own %@AB@%matherr
  1166. %@AB@%%@AE@%function and that function alters global variables. If you have written a
  1167. %@AB@%matherr %@AE@%function to handle floating-point errors, and your function has side
  1168. effects, use the%@AB@% function %@AE@%pragma to instruct the compiler not to generate
  1169. intrinsic code for math functions.%@NL@%
  1170. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1171. %@NL@%
  1172.  
  1173. If you want the compiler to generate intrinsic functions for only a subset
  1174. of the functions listed above, use the %@AB@%intrinsic %@AE@%pragma rather than the /Oi
  1175. option. The %@AB@%intrinsic%@AE@% pragma has the following format:  %@NL@%
  1176. %@NL@%
  1177. %@AS@%  #pragma intrinsic( function1, ... )%@AE@%%@NL@%
  1178. %@NL@%
  1179. If you want to have intrinsic functions generated for most of the functions
  1180. above and function calls for only a few, compile with the /Oi option and
  1181. force function use with the %@AB@%function %@AE@%pragma. The %@AB@%function%@AE@% pragma has the
  1182. following format:  %@NL@%
  1183. %@NL@%
  1184. %@AS@%  #pragma function( function1, ... )%@AE@%%@NL@%
  1185. %@NL@%
  1186. The following code illustrates the use of the %@AB@%intrinsic%@AE@% pragma:  %@NL@%
  1187. %@NL@%
  1188. %@AS@%  #pragma intrinsic(abs) 
  1189. %@AS@%  
  1190. %@AS@%  void main( void )
  1191. %@AS@%  {
  1192. %@AS@%      int i, j;
  1193. %@AS@%  
  1194. %@AS@%      i = big_routine_1();
  1195. %@AS@%      j = abs( i );
  1196. %@AS@%      big_routine_2( j );
  1197. %@AS@%  }%@AE@%%@NL@%
  1198. %@NL@%
  1199. Generating intrinsic functions for this program causes the call to %@AB@%abs %@AE@%to be
  1200. replaced with assembly-language code that takes the absolute value of a
  1201. number. The program will execute more quickly because the function-calling
  1202. overhead is no longer required when %@AB@%abs %@AE@%is called.  %@NL@%
  1203. %@NL@%
  1204. In the previous example, the overall speed increase is small because there
  1205. is only a single call to %@AB@%abs%@AE@%. In the following example, where the call to
  1206. %@AB@%abs %@AE@%is in a loop and there are many calls, you can save a significant amount
  1207. of execution time by generating intrinsic functions.  %@NL@%
  1208. %@NL@%
  1209. %@AS@%  #pragma intrinsic( abs )
  1210. %@AS@%  void main( void )
  1211. %@AS@%  {
  1212. %@AS@%  int i, j, x;%@AE@%%@NL@%
  1213. %@NL@%
  1214. %@AS@%  for( j = 0; j < 1000; j++ )
  1215. %@AS@%      {
  1216. %@AS@%          for( i = 0; i < 1000; i++)
  1217. %@AS@%          {
  1218. %@AS@%              x += abs( i - j );
  1219. %@AS@%          }
  1220. %@AS@%     }
  1221. %@AS@%     printf( "The value of x is %d\n", x ); 
  1222. %@AS@%  }%@AE@%%@NL@%
  1223. %@NL@%
  1224. The following is a list of restrictions on using the intrinsic forms of
  1225. function calls:  %@NL@%
  1226. %@NL@%
  1227. %@NL@%
  1228.   ■   Do not use the intrinsic forms of the floating-point math functions
  1229.       with the alternate math libraries (%@AI@%m%@AE@%LIBCA%@AI@%y%@AE@%.LIB).%@NL@%
  1230. %@NL@%
  1231.   ■   Do not use the intrinsic forms of the floating-point math functions in
  1232.       OS/2 dynamic-link libraries (DLLs) because you must use the alternate
  1233.       math library with LLIBCDLL.LIB.%@NL@%
  1234. %@NL@%
  1235.   ■   If you use the /Ox (maximum optimization) option, you are enabling the
  1236.       /Oi (generate intrinsic functions) option. Be careful that your use of
  1237.       /Ox does not conflict with the points listed previously.%@NL@%
  1238. %@NL@%
  1239. %@NL@%
  1240. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1241. NOTE
  1242.  
  1243. %@AI@%Intrinsic versions of %@AB@%_enable%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%_disable%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%inp%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%outp%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%inpw%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%outpw 
  1244. %@AB@%%@AE@%%@AE@%%@AI@%do not work under OS/2. You must use the library versions. You can use the
  1245. %@AI@%%@AE@%%@AI@%%@AB@%function %@AE@%%@AE@%%@AI@%pragm%@AE@%%@AI@%a to force these functions to become library calls.%@AE@%%@AE@%%@NL@%
  1246. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1247. %@NL@%
  1248. %@NL@%
  1249. %@3@%%@CR:C6A00010012 @%%@AB@%1.5.3  Assuming No Aliasing (/Oa and /Ow)%@AE@%%@EH@%%@NL@%
  1250. %@NL@%
  1251. An "alias" is a name used to refer to a memory location already referred to
  1252. by a different name. Because a memory access takes more time than it takes
  1253. to access the CPU's registers, the compiler tries to store frequently used
  1254. variables in registers. However, the aliasing reduces the extent to which a
  1255. compiler can keep variables in registers.  %@NL@%
  1256. %@NL@%
  1257. A pointer is a reference to a memory location. Because the value of a
  1258. pointer is not determined until the program is run, the compiler has no way
  1259. of knowing which memory location will be modified when the program executes;
  1260. it could be a reference to a variable. Therefore, the compiler must assume
  1261. that any time the value pointed to by any pointer changes, the value of any
  1262. variable might also change. This limits the extent to which the compiler can
  1263. move values from memory to registers.  %@NL@%
  1264. %@NL@%
  1265. The /Oa option tells the compiler to ignore the possibility of multiple
  1266. aliases for a memory location. In the list that follows, the term
  1267. "reference" means read or write; that is, whether a variable is on the
  1268. left-hand side of an assignment statement or the right-hand side, you are
  1269. still referring to it. In addition, any function calls that use a variable
  1270. as a parameter are references to that variable. When you tell the compiler
  1271. to assume that you are not doing aliasing, it expects that the following
  1272. rules are being followed for any variable not declared as %@AB@%volatile%@AE@%:  %@NL@%
  1273. %@NL@%
  1274. %@NL@%
  1275.   ■   If a variable is used directly, no pointers are used to reference that
  1276.       variable.%@NL@%
  1277. %@NL@%
  1278.   ■   If a pointer is used to refer to a variable, that variable is not
  1279.       referred to directly.%@NL@%
  1280. %@NL@%
  1281.   ■   If a pointer is used to modify a memory location, no other pointers
  1282.       are used to access the same memory location.%@NL@%
  1283. %@NL@%
  1284. %@NL@%
  1285. To clarify how these rules affect your code, consider the following example:
  1286. %@NL@%
  1287. %@NL@%
  1288. %@AS@%  char    p;
  1289. %@AS@%  char    *ptr_p;
  1290. %@AS@%  
  1291. %@AS@%  ptr_p = &p;    /* Take the address of p. */%@AE@%%@NL@%
  1292. %@NL@%
  1293. You can now refer either to %@AS@% *ptr_p %@AE@% or to %@AS@% p%@AE@%, but not to both within the
  1294. same function. If you must refer to the variable by both names, you are
  1295. using aliases.  %@NL@%
  1296. %@NL@%
  1297. Code referring to the same location with two pointers uses aliases. For
  1298. example,  %@NL@%
  1299. %@NL@%
  1300. %@AS@%  char    *p_buf;
  1301. %@AS@%  char    *p_alias;
  1302. %@AS@%  
  1303. %@AS@%  if( (p_alias = p_buf = malloc( 5000 )) == NULL )
  1304. %@AS@%      return;
  1305. %@AS@%  else
  1306. %@AS@%  {
  1307. %@AS@%      .
  1308. %@AS@%      .
  1309. %@AS@%      .
  1310. %@AS@%  }%@AE@%%@NL@%
  1311. %@NL@%
  1312. The code in the example above is common. It demonstrates dynamically
  1313. allocating a block of memory from the heap, and preserving the original
  1314. address in %@AS@% p_buf%@AE@%. The program then performs all pointer arithmetic on the
  1315. alias %@AS@% p_alias%@AE@%. When the function finishes with the block of memory, %@AS@% p_buf %@AE@%
  1316. is a valid argument for the %@AB@%free %@AE@%function because it still contains the
  1317. original address.  %@NL@%
  1318. %@NL@%
  1319. %@AU@% The /Oa and /Ow options tell the compiler that you have not used aliases in
  1320. %@AU@%your code.%@AE@%  %@NL@%
  1321. %@NL@%
  1322. The difference between the /Oa and the /Ow option is that when you use /Oa
  1323. you specify that you will not be doing aliasing (which allows the compiler
  1324. to perform significant optimizations that might not otherwise have been
  1325. possible), and that function calls are safe. The /Ow option is similar to
  1326. the /Oa option, except that after a function call, pointer variables must be
  1327. reloaded from memory.  %@NL@%
  1328. %@NL@%
  1329. Here is an example of a program that would be a poor candidate for the /Oa
  1330. or /Ow optimization option:  %@NL@%
  1331. %@NL@%
  1332. %@AS@%  int g;
  1333. %@AS@%  
  1334. %@AS@%  void main( void )
  1335. %@AS@%  {
  1336. %@AS@%      add_em( &g );
  1337. %@AS@%  }
  1338. %@AS@%  
  1339. %@AS@%  int add_em( int *p )
  1340. %@AS@%  {
  1341. %@AS@%      *p = 2;          /* Assign a value to an alias for g. */
  1342. %@AS@%      g = 3;           /* Assign a value directly to g. */
  1343. %@AS@%      return( *p + g );
  1344. %@AS@%  }%@AE@%%@NL@%
  1345. %@NL@%
  1346. In the function %@AS@% add_em%@AE@%, both %@AS@% g %@AE@% and %@AS@% *p %@AE@% refer to the same memory
  1347. location. This location is first assigned %@AS@% 2%@AE@%, then %@AS@% 3%@AE@%. The value pointed to
  1348. by %@AS@% *p %@AE@% (the alias for %@AS@% g%@AE@%) is then added to %@AS@% g%@AE@%, and the result is returned
  1349. to the main program. If you do not use the /Oa command-line option, the
  1350. compiler assumes that the reference to %@AS@% *p %@AE@% could refer to the same memory
  1351. location as does %@AS@% g %@AE@% and makes no attempt to use a register to store the
  1352. value of either. If, however, you do specify the /Oa option, the compiler
  1353. assumes that %@AS@% g %@AE@% and %@AS@% *p %@AE@% refer to different memory locations and stores
  1354. each in a different register. At the return statement, %@AS@% g %@AE@% will have a
  1355. different value than %@AS@% *p%@AE@%, even though both aliases should actually contain
  1356. the same value.  %@NL@%
  1357. %@NL@%
  1358. Note that the compiler keeps values in registers for only a limited time. If
  1359. different aliases to a memory location occur in different functions, for
  1360. example, they will not cause unexpected results. When in doubt, avoid
  1361. aliasing.  %@NL@%
  1362. %@NL@%
  1363. %@AU@% Bugs involving aliasing are difficult to spot.%@AE@%  %@NL@%
  1364. %@NL@%
  1365. Aliasing bugs most frequently show up as corruption of data. If you find
  1366. that global or local variables are being assigned seemingly random values,
  1367. take the following steps to determine if you have a problem with
  1368. optimization and aliasing:  %@NL@%
  1369. %@NL@%
  1370. %@NL@%
  1371.   ■   Compile the program with /Od (disable optimizations).%@NL@%
  1372. %@NL@%
  1373.   ■   If the program works when compiled with the /Od option, check your
  1374.       normal compile options for the /Oa option (assume no aliasing).%@NL@%
  1375. %@NL@%
  1376.   ■   If you were using the /Oa option, fix your compile options so that /Oa
  1377.       is not specified.%@NL@%
  1378. %@NL@%
  1379. %@NL@%
  1380. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1381. NOTE
  1382. %@AI@%You can instruct the compiler to disable optimizations that are unsafe with
  1383. %@AI@%code that does aliasing by using the %@AB@%optimize%@AE@%%@AI@% pragma with the %@AE@%%@AI@%%@AB@%a%@AE@%%@AE@%%@AI@% or %@AE@%%@AI@%%@AB@%w%@AE@%%@AE@%%@AI@% option.%@CR:C6A00010013 @%%@AE@%%@AE@%%@NL@%
  1384. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1385. %@NL@%
  1386. %@NL@%
  1387. %@3@%%@CR:C6A00010014 @%%@AB@%1.5.4  Performing Loop Optimizations (/Ol)%@AE@%%@EH@%%@NL@%
  1388. %@NL@%
  1389. The /Ol option enables a set of optimizations involving loops. Because loops
  1390. involve sections of code that are executed repeatedly, they are targets for
  1391. optimization. These optimizations all involve moving code or rewriting code
  1392. so that it executes faster.  %@NL@%
  1393. %@NL@%
  1394. Loop optimization can be turned on with the /Ol option or with the %@AB@%loop_opt %@AE@%
  1395. pragma. The following line enables loop optimization for all subsequent
  1396. functions:  %@NL@%
  1397. %@NL@%
  1398. %@AS@%  #pragma loop_opt( on )%@AE@%%@NL@%
  1399. %@NL@%
  1400. The following line turns it off:  %@NL@%
  1401. %@NL@%
  1402. %@AS@%  #pragma loop_opt( off )%@AE@%%@NL@%
  1403. %@NL@%
  1404. %@AU@% The /Ol option removes invariant code.%@AE@%  %@NL@%
  1405. %@NL@%
  1406. An optimal loop contains only expressions whose values change through each
  1407. execution of the loop. Any subexpression whose value is constant should be
  1408. evaluated before the body of the loop is executed. Unfortunately, these
  1409. subexpressions are not always readily apparent. The optimizer can remove
  1410. many of these expressions from the body of a loop at compile time. This
  1411. example illustrates invariant code in a loop:  %@NL@%
  1412. %@NL@%
  1413. %@AS@%  i = -100;
  1414. %@AS@%  while( i < 0 )
  1415. %@AS@%  {
  1416. %@AS@%      i += x + y;
  1417. %@AS@%  }%@AE@%%@NL@%
  1418. %@NL@%
  1419. In the preceding example, the expression %@AS@% x + y %@AE@% does not change in the loop
  1420. body. Loop optimization removes this subexpression from the body of the loop
  1421. so that it is only executed once, not every time the loop body is executed.
  1422. The optimizer will change the code to the following fragment:  %@NL@%
  1423. %@NL@%
  1424. %@AS@%  i = -100;
  1425. %@AS@%  t = x + y;
  1426. %@AS@%  while( i < 0 )
  1427. %@AS@%  {
  1428. %@AS@%      i += t;
  1429. %@AS@%  }%@AE@%%@NL@%
  1430. %@NL@%
  1431. Loop optimization is much more effective when the compiler can assume no
  1432. aliasing. While you can use loop optimization without the /Oa or /Ow option,
  1433. use /Oa to ensure that the most options possible are used.  %@NL@%
  1434. %@NL@%
  1435. Here is a code fragment that could have an aliasing problem:  %@NL@%
  1436. %@NL@%
  1437. %@AS@%  i = -100;
  1438. %@AS@%  while( i < 0 )
  1439. %@AS@%  {
  1440. %@AS@%      i += x + y;
  1441. %@AS@%      *p = i;
  1442. %@AS@%  }%@AE@%%@NL@%
  1443. %@NL@%
  1444. If you do not specify the /Oa option, the compiler must assume that either %@AS@%
  1445. %@AS@%x %@AE@% or %@AS@% y %@AE@% could be modified by the assignment to %@AS@% *p%@AE@%. Therefore, the
  1446. compiler cannot assume the subexpression %@AS@% x + y %@AE@% is constant for each loop
  1447. iteration. If you specify that you are not doing any aliasing (with the /Oa
  1448. option), the compiler assumes that modifying %@AS@% *p %@AE@% cannot affect either %@AS@% x %@AE@%
  1449. or %@AS@% y%@AE@%, and that the subexpression is indeed constant and can be removed from
  1450. the loop, as in the previous example.  %@NL@%
  1451. %@NL@%
  1452. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1453. NOTE
  1454.  
  1455. %@AI@%All loop optimizations specified by the /Ol option or the %@AB@%loop_opt%@AE@%%@AI@% pragma
  1456. %@AI@%are safe optimizations. To enable aggressive loop optimizations, you must
  1457. %@AI@%use the enable aggressive optimizations (/Oz) option. While the
  1458. %@AI@%optimizations enabled by the combination of /Ol and /Oz are not safe for all
  1459. %@AI@%cases, they will work properly for most programs.%@AE@%%@AE@%%@NL@%
  1460. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1461. %@NL@%
  1462. %@NL@%
  1463. %@3@%%@CR:C6A00010015 @%%@AB@%1.5.5  Disabling Unsafe Loop Optimizations (/On)%@AE@%%@EH@%%@NL@%
  1464. %@NL@%
  1465. The disable unsafe loop optimizations (/On) option is an obsolescent option
  1466. and is only retained for compatibility with existing makefiles. Loop
  1467. optimizations are, by default, safe optimizations. The /On option is the
  1468. default and has the opposite effect of the /Oz (enable aggressive
  1469. optimizations) option.  %@NL@%
  1470. %@NL@%
  1471. %@NL@%
  1472. %@3@%%@CR:C6A00010016 @%%@AB@%1.5.6  Enabling Aggressive Optimizations (/Oz)%@AE@%%@EH@%%@NL@%
  1473. %@NL@%
  1474. The compiler can perform extremely aggressive optimizations. These
  1475. optimizations produce high code quality both in terms of speed and size.
  1476. Certain programs, however, cannot be optimized with the technologies enabled
  1477. by the /Oz option. For these programs, you should not specify this option;
  1478. you can still use all other optimization options.  %@NL@%
  1479. %@NL@%
  1480. Because the optimization strategies enabled by the /Oz option are so
  1481. aggressive, they are not part of the maximum optimization (/Ox) option.  %@NL@%
  1482. %@NL@%
  1483. Examples of the effects of the /Oz option are  %@NL@%
  1484. %@NL@%
  1485. %@NL@%
  1486.   ■   Loop optimization (/Ol). Loop optimization enables a technology that
  1487.       anticipates program flow and tries to remove invariant expressions
  1488.       from loops. When you specify the enable aggressive optimizations
  1489.       option (/Oz), the compiler removes invariant expressions even when it
  1490.       might cause an error. Errors with the enable aggressive optimizations
  1491.       option occur most often when an invariant expression that can cause an
  1492.       exception is protected by an %@AB@%if%@AE@% statement. The invariant expression is
  1493.       hoisted out of the loop body, causing it to be evaluated prior to the
  1494.       evaluation of the %@AB@%if%@AE@% statement that was designed to protect it. Here
  1495.       are two examples that illustrate this problem:
  1496. %@NL@%
  1497. %@AS@%        for( i = 0; i  100; ++i )
  1498. %@AS@%            if( float_val != 0.0F )
  1499. %@AS@%            /* Protect against divide-by-zero. */
  1500. %@AS@%                float_result = pi / float_val;%@AE@%%@NL@%
  1501.  
  1502. %@NL@%
  1503. %@AS@%        while( condition )
  1504. %@AS@%            if( ptr_val != NULL )
  1505. %@AS@%              /* Protect pointer dereference. */
  1506. %@AS@%                char_var = *ptr_val;%@AE@%%@NL@%
  1507. %@NL@%
  1508. %@NL@%
  1509.   ■   Global register allocation (/Oe). The enable aggressive optimizations
  1510.       option enables some register allocation strategies that can cause
  1511.       invalid segment selectors to be placed in registers. Although this
  1512.       problem is benign in DOS, it causes protection faults in OS/2.%@NL@%
  1513. %@NL@%
  1514. %@NL@%
  1515. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1516. NOTE
  1517.  
  1518. %@AI@%You can instruct the compiler to enable aggressive optimizations on a
  1519. %@AI@%function-by-function basis by using the %@AB@%optimize%@AE@%%@AI@% pragma with the %@AE@%%@AI@%%@AB@%z %@AE@%%@AE@%%@AI@%option.%@AE@%%@AE@%%@NL@%
  1520. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1521. %@NL@%
  1522. %@NL@%
  1523. %@3@%%@CR:C6A00010017 @%%@AB@%1.5.7  Removing Stack Probes (/Gs)%@AE@%%@EH@%%@NL@%
  1524. %@NL@%
  1525. Every time a function is called, the stack provides space for all parameters
  1526. and local variables declared in that function. A short assembly function
  1527. that checks for a stack overflow condition is then called. Stack overflows
  1528. are usually caused either by infinite loops or by runaway recursive
  1529. routines. Such errors can also be caused by extremely large parameters or
  1530. local variables.  %@NL@%
  1531. %@NL@%
  1532. Stack probes can be important during program development. Stack-overflow
  1533. errors alert you to problems in your code. When the program has been tested,
  1534. however, stack checking often becomes unnecessary. The compiler allows you
  1535. to remove stack-checking code with either the /Gs option or the %@AB@%check_stack
  1536. %@AB@%%@AE@%pragma. Eliminating stack probes produces programs that are smaller and that
  1537. run more quickly.  %@NL@%
  1538. %@NL@%
  1539. %@NL@%
  1540. %@3@%%@CR:C6A00010018 @%%@AB@%1.5.8  Enabling Global Register Allocation (/Oe)%@AE@%%@EH@%%@NL@%
  1541. %@NL@%
  1542. The global register allocation option (/Oe) instructs the compiler to
  1543. analyze your program and allocate CPU registers as efficiently as possible.
  1544. Without the global register allocation option, the compiler uses the CPU's
  1545. registers for several purposes:  %@NL@%
  1546. %@NL@%
  1547. %@NL@%
  1548.   ■   Holding temporary copies of variables%@NL@%
  1549. %@NL@%
  1550.   ■   Holding variables declared with the %@AB@%register%@AE@% keyword%@NL@%
  1551. %@NL@%
  1552.   ■   Passing parameters to functions declared with the %@AB@%_fastcall%@AE@% keyword
  1553.       (or functions in programs compiled with the /Gr command-line option)%@NL@%
  1554. %@NL@%
  1555. %@NL@%
  1556. When you enable global register allocation, the compiler ignores the
  1557. %@AB@%register%@AE@% keyword and allocates register storage to variables (and possibly
  1558. to common subexpressions). The compiler allocates register storage to
  1559. variables or subexpressions according to frequency of use. Because of the
  1560. limited number of physical registers, variables held in registers are
  1561. sometimes placed back in memory to free the register for another use. Here
  1562. is a C program example that demonstrates how the compiler might rewrite your
  1563. code to accomplish this:  %@NL@%
  1564. %@NL@%
  1565. %@AS@%  /* Original program */
  1566. %@AS@%  
  1567. %@AS@%  func()
  1568. %@AS@%  {
  1569. %@AS@%      int i, j;
  1570. %@AS@%      char *pc;
  1571. %@AS@%  
  1572. %@AS@%      for( i = 0; i < 1000; ++i )
  1573. %@AS@%      {
  1574. %@AS@%          j = i / 3;
  1575. %@AS@%          *pc++ = (char)i;
  1576. %@AS@%      }
  1577. %@AS@%  
  1578. %@AS@%      for( j = 0, --pc; j < 1000; 
  1579. %@AS@%          ++j, --pc )
  1580. %@AS@%          *pc--;
  1581. %@AS@%  }%@AE@%%@NL@%
  1582. %@NL@%
  1583. %@AS@%  /* Example of how the compiler might optimize the
  1584. %@AS@%   * code to move i and j in and out of registers */
  1585. %@AS@%  
  1586. %@AS@%  func()
  1587. %@AS@%  {
  1588. %@AS@%      int i, j;
  1589. %@AS@%      char *pc;
  1590. %@AS@%  
  1591. %@AS@%      { 
  1592. %@AS@%      register int i; /* i is in a register for this block. */
  1593. %@AS@%          for( i = 0; i < 1000; ++i )
  1594. %@AS@%          {
  1595. %@AS@%              j = i / 3;
  1596. %@AS@%              *pc++ = (char)i;
  1597. %@AS@%          }
  1598. %@AS@%      }
  1599. %@AS@%  
  1600. %@AS@%      {
  1601. %@AS@%      register int j; /* j is in a register for this block. */
  1602. %@AS@%          for( j = 0, --pc; j < 1000; 
  1603. %@AS@%              ++j, --pc )
  1604. %@AS@%              *pc--;
  1605. %@AS@%      }
  1606. %@AS@%  }%@AE@%%@NL@%
  1607. %@NL@%
  1608. In the preceding example, there are blocks (enclosed in curly braces) whose
  1609. only purpose is to delimit the span of code across which variables should
  1610. remain in registers.  %@NL@%
  1611. %@NL@%
  1612. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1613. NOTE
  1614.  
  1615. %@AI@%You can enable or disable global register allocation on a
  1616. %@AI@%function-by-function basis using the %@AB@%optimize%@AE@%%@AI@% pragma with the %@AE@%%@AI@%%@AB@%e%@AE@%%@AE@%%@AI@% option.%@CR:C6A00010019 @%%@AE@%%@AE@%%@NL@%
  1617. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1618. %@NL@%
  1619. %@NL@%
  1620. %@3@%%@CR:C6A00010020 @%%@AB@%1.5.9  Enabling Common Subexpression Optimization (/Oc and /Og)%@AE@%%@EH@%%@NL@%
  1621. %@NL@%
  1622. When you use option /Og (enable global common subexpression optimizations),
  1623. the compiler searches entire functions for common subexpressions. Option /Oc
  1624. (default common subexpression optimization) examines only short sections of
  1625. code for common subexpressions. You can disable default common subexpression
  1626. optimization with the /Od option. For more information about common
  1627. subexpression optimization, see Section 1.4, "Default Optimization."  %@NL@%
  1628. %@NL@%
  1629. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1630. NOTE
  1631.  
  1632. %@AI@%You can enable or disable block-scope common subexpression optimization on a
  1633. %@AI@%function-by-function basis using the %@AB@%optimize%@AE@%%@AI@% pragma with the %@AE@%%@AI@%%@AB@%c %@AE@%%@AE@%%@AI@%option. You
  1634. %@AI@%can enable or disable global common subexpression optimization on a
  1635. %@AI@%function-by-function basis using the %@AE@%%@AI@%%@AB@%optimize%@AE@%%@AE@%%@AI@% pragma with the %@AE@%%@AI@%%@AB@%g %@AE@%%@AE@%%@AI@%option.%@CR:C6A00010021 @%%@AE@%%@AE@%%@NL@%
  1636. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1637. %@NL@%
  1638. %@NL@%
  1639. %@3@%%@CR:C6A00010022 @%%@AB@%1.5.10  Achieving Consistent Floating-Point Results (/Op)%@AE@%%@EH@%%@NL@%
  1640. %@NL@%
  1641. Floating-point numbers stored in memory use either 32, 64, or 80 bits,
  1642. depending on whether they are of type %@AB@%float%@AE@%, type %@AB@%double%@AE@%, or type %@AB@%long
  1643. %@AB@%double%@AE@%. The 80%@AI@%x%@AE@%87 family of coprocessors uses 80-bit registers for all
  1644. operations. If a value of type %@AB@%float%@AE@% or type %@AB@%double%@AE@% is kept in these
  1645. registers through a number of operations, it will be more accurate than if
  1646. that value is moved to and from memory between operations.  %@NL@%
  1647. %@NL@%
  1648. Because of the difference in precision between memory and register
  1649. representation of a floating-point number, a value stored in memory is not
  1650. always equal to the same value in the 80%@AI@%x%@AE@%87 register.  %@NL@%
  1651. %@NL@%
  1652. The difference in precision primarily affects strict equality or strict
  1653. inequality tests (%@AB@%==%@AE@% and %@AB@%!=%@AE@%); however, relational tests of magnitude (%@AB@%>%@AE@%, %@AB@%>=%@AE@%,
  1654. %@AB@%%@AE@%, and %@AB@%%@AE@%) can behave erroneously if the coprocessor is able to maintain
  1655. significant digits that memory variables cannot.  %@NL@%
  1656. %@NL@%
  1657. You can avoid the difference in precision by using the /Op option. This
  1658. option forces floating-point values to be written to memory between
  1659. floating-point operations. While storing these values to memory reduces the
  1660. precision of floating-point expressions, it also ensures that these
  1661. expressions will produce consistent results regardless of the rest of the
  1662. code.  %@NL@%
  1663. %@NL@%
  1664. You can change the handling of floating-point results on a
  1665. function-by-function basis using the %@AB@%optimize %@AE@%pragma with the %@AB@%p %@AE@%option.%@CR:C6A00010023 @%  %@NL@%
  1666. %@NL@%
  1667. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1668. NOTE
  1669.  
  1670. %@AI@%Using the /Op option suppresses other optimizations because the
  1671. %@AI@%floating-point registers are not available for storage of intermediate
  1672. %@AI@%results. Because you suppress these optimizations, code compiled with the
  1673. %@AI@%/Op option executes more slowly than code compiled without this option.
  1674. %@AI@%Careful coding practices, especially in tests of strict equality and
  1675. %@AI@%inequality, can alleviate the need for this option.%@AE@%%@NL@%
  1676. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1677. %@NL@%
  1678. %@NL@%
  1679. %@3@%%@CR:C6A00010024 @%%@AB@%1.5.11  Using the 80186, 80188, or 80286 Processor (/G0, /G1, /G2)%@AE@%%@EH@%%@NL@%
  1680. %@NL@%
  1681. The compiler generates 8086 object code (/G0) unless you take special steps.
  1682. Because the newer processors (the 80186, 80188, and 80286) are
  1683. backwardcompatible with the 8086 instruction set, using this instruction set
  1684. ensures compatibility with all 80%@AI@%x%@AE@%86-based computers. While you gain
  1685. compatibility across the entire family of 80%@AI@%x%@AE@%86 processors, you lose the
  1686. advantage of some of the more powerful instructions in the newer processors.
  1687. %@NL@%
  1688. %@NL@%
  1689. If you know your program will only be running on an 80186, 80188, or 80286
  1690. processor, you can cause the compiler to generate instructions specific to
  1691. these processors. These instructions increase the speed of your program, but
  1692. you lose compatibility with machines that use older processors in the 80%@AI@%x%@AE@%86
  1693. family. Table 1.1 lists the options for processor-specific code generation:
  1694. %@NL@%
  1695. %@NL@%
  1696. %@AB@%Table 1.1  %@AB@%Processor Compatibility%@AE@%%@AE@%
  1697.  
  1698. %@TH:   6   432 02 23 53 @%
  1699. Command-Line Option    Compatible Processors
  1700. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1701. /G0                    8088, 8086, 80188, 80186, 80286, 80388, 80486
  1702. /G1                    80188, 80186, 80286, 80386, 80486
  1703. /G2                    80286, 80386, 80486
  1704. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1705. %@TE:   6   432 02 23 53 @%
  1706.  
  1707. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1708. NOTE
  1709.  
  1710. %@AI@%When developing only for OS/2, always use the /G2 option, because OS/2 does
  1711. %@AI@%not run on the 8086, 8088, 80186, or 80188. Do not use /G2 for Family
  1712. %@AI@%Applications because they might be run on machines with 8088, 8086, 80188,
  1713. %@AI@%or 80186 processors.%@AE@%%@NL@%
  1714. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1715. %@NL@%
  1716. %@NL@%
  1717. %@3@%%@CR:C6A00010025 @%%@AB@%1.5.12  Optimizing for Maximum Efficiency (/Ox)%@AE@%%@EH@%%@NL@%
  1718. %@NL@%
  1719. The /Ox option combines a number of different optimizations:  %@NL@%
  1720. %@NL@%
  1721. %@NL@%
  1722.   ■   Enable global register allocation (/Oe)%@NL@%
  1723. %@NL@%
  1724.   ■   Enable global common subexpression optimization (/Og)%@NL@%
  1725. %@NL@%
  1726.   ■   Enable block-scoped common subexpression optimization (/Oc)%@NL@%
  1727. %@NL@%
  1728.   ■   Generate intrinsic functions (/Oi)%@NL@%
  1729. %@NL@%
  1730.   ■   Perform loop optimizations (/Ol)%@NL@%
  1731. %@NL@%
  1732.   ■   Optimize for speed (/Ot)%@NL@%
  1733. %@NL@%
  1734.   ■   Remove stack probes (/Gs)%@NL@%
  1735. %@NL@%
  1736. %@NL@%
  1737. %@AU@% Use /Ozax /Gr to get the fastest program.%@AE@%  %@NL@%
  1738. %@NL@%
  1739. The /Ox option does not include several optimizations that can improve code
  1740. efficiency: /Oa (assume no aliasing), /Oz (enable aggressive optimizations),
  1741. and /Gr (use fastcall calling convention). Before enabling these
  1742. optimizations, you should read the sections that describe the /Oa and /Oz
  1743. options and the fastcall calling convention to determine if they are
  1744. appropriate for your application.  %@NL@%
  1745. %@NL@%
  1746. %@AU@% Use the optimize pragma to reduce code size.%@AE@%  %@NL@%
  1747. %@NL@%
  1748. If you are more concerned with executable file size than execution time, use
  1749. the /Ox and /Gs options, then issue the %@AB@%optimize %@AE@%pragma as follows:  %@NL@%
  1750. %@NL@%
  1751. %@AS@%  #pragma optimize( "t", off )%@AE@%%@NL@%
  1752. %@NL@%
  1753. This set of options produces the smallest possible code, while also
  1754. performing some speed optimizations.  %@NL@%
  1755. %@NL@%
  1756. %@NL@%
  1757. %@2@%%@CR:C6A00010026 @%%@AB@%1.6  Linker (LINK) Options that Control Optimization%@AE@%%@EH@%%@NL@%
  1758. %@NL@%
  1759. Most code optimization is performed before the object file is produced.
  1760. There are four optimizations that the linker can perform to speed program
  1761. execution and reduce the disk space used by an executable file.  %@NL@%
  1762. %@NL@%
  1763. %@NL@%
  1764. %@3@%%@CR:C6A00010027 @%%@AB@%1.6.1  Enabling Far Call Optimization (/FARCALLTRANSLATION)%@AE@%%@EH@%%@NL@%
  1765. %@NL@%
  1766. You can call a function two ways. In a far call, the function is called
  1767. using both the segment and the offset of the function. This allows a program
  1768. to call a routine outside a 64K segment. In a near call, both the calling
  1769. statement and the function must be located in the same segment. Only the
  1770. offset is used to access the function; the segment address is implicit. You
  1771. can only use near calls to routines located in the same segment.%@CR:C6A00010028 @%%@CR:C6A00010029 @%  %@NL@%
  1772. %@NL@%
  1773. Because of the architecture of the processor, near function calls execute
  1774. faster than far calls. The decision to declare functions as near or far is
  1775. often made when selecting a memory model. As it is difficult to determine
  1776. where the linker will place a given function in memory, it is impractical
  1777. for the programmer to choose the way a function is called.  %@NL@%
  1778. %@NL@%
  1779. %@AU@% Use /FARCALLTRANSLATION with medium, large, and huge model programs.%@AE@%  %@NL@%
  1780. %@NL@%
  1781. The /FARCALLTRANSLATION option enables far call optimization. When you use
  1782. this option, any function calls within the same segment as the function
  1783. being called are converted to near calls. This optimization has no effect if
  1784. you have selected the tiny, small, or compact model, because all calls are
  1785. already near calls.  %@NL@%
  1786. %@NL@%
  1787. The abbreviation for the /FARCALLTRANSLATION option is /F.  %@NL@%
  1788. %@NL@%
  1789. %@NL@%
  1790. %@4@%%@AB@%How /FARCALLTRANSLATION Affects Your Code%@AE@%%@EH@%%@NL@%
  1791. %@NL@%
  1792. The linker can perform a form of post-optimization (an optimization that
  1793. occurs after most of the actual code generation is complete) that translates
  1794. far calls into near calls when possible. This optimization allows a given
  1795. function to be called with both near and far calls in the same program. To
  1796. perform this translation, the linker takes a section of object code such as
  1797. %@NL@%
  1798. %@NL@%
  1799. %@AS@%  CALL    FAR    _func%@AE@%%@NL@%
  1800. %@NL@%
  1801. where %@AS@% func %@AE@% is defined in the current segment, and replaces it with the
  1802. following code:  %@NL@%
  1803. %@NL@%
  1804. %@AS@%  PUSH    CS
  1805. %@AS@%  CALL    NEAR    _func
  1806. %@AS@%  NOP%@AE@%%@NL@%
  1807. %@NL@%
  1808. This substitution works because the linker has inserted %@AS@% PUSH CS %@AE@% to place a
  1809. far return address on the stack.  %@NL@%
  1810. %@NL@%
  1811. %@AU@% Use /FARCALLTRANSLATION with /PACKCODE.%@AE@%  %@NL@%
  1812. %@NL@%
  1813. The /FARCALLTRANSLATION option is most effective when used in conjunction
  1814. with the /PACKCODE option discussed in Section 1.6.2. Using the /PACKCODE
  1815. option causes far calls that were intersegment to become intrasegment calls.
  1816. The /FARCALLTRANSLATION feature can then take advantage of the new grouping
  1817. to translate all intrasegment far calls into near calls.%@CR:C6A00010030 @%  %@NL@%
  1818. %@NL@%
  1819. %@NL@%
  1820. %@4@%%@AB@%Benefits of /FARCALLTRANSLATION%@AE@%%@EH@%%@NL@%
  1821. %@NL@%
  1822. The /FARCALLTRANSLATION option is of significant benefit to protected-mode
  1823. programs. Table 1.2 illustrates why.  %@NL@%
  1824. %@NL@%
  1825. %@AB@%Table 1.2  %@AB@%Processor Clock Cycles for Calling Sequence%@AE@%%@AE@%
  1826.  
  1827. %@TH:  34  1635 03 20 15 11 15 15 @%
  1828.                     %@AB@%Cycles  (Real%@AE@%             %@AB@%Cycles  %@AE@%
  1829.                     %@AB@%Mode)%@AE@%                     %@AB@%(Protected %@AE@%
  1830.                                               %@AB@%Mode)%@AE@%
  1831. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1832. %@AB@%%@AE@%                                   %@AB@%%@AE@%           %@AB@%%@AE@%               %@AB@%%@AE@%
  1833. %@AB@%Instructions%@AE@%        286            %@AB@%386%@AE@%        %@AB@%286%@AE@%            %@AB@%386%@AE@%
  1834.  
  1835. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1836.  
  1837. Far Function Call                             
  1838.  
  1839. %@AS@%CALL FAR PTR _func%@AE@%  13             17         26             34
  1840.  
  1841. Total               13             17         26             34
  1842.  
  1843. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1844.  
  1845. Near Function Call                            
  1846.  
  1847. %@AS@%PUSH CS%@AE@%             3              2          3              2
  1848.  
  1849. %@AS@%CALL NEAR PTR %@AE@%      7              7          7              7
  1850. %@AS@%_func%@AE@%                                                        
  1851.  
  1852. %@AS@%NOP%@AE@%                 3              3          3              3
  1853.  
  1854. Total               13             12         13             12
  1855.  
  1856. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1857.  
  1858. Savings             0              5          13             22
  1859.  
  1860. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1861.  
  1862. %@TE:  34  1635 03 20 15 11 15 15 @%
  1863.  
  1864. %@NL@%
  1865. %@3@%%@CR:C6A00010031 @%%@AB@%1.6.2  Packing Code (/PACKCODE)%@AE@%%@EH@%%@NL@%
  1866. %@NL@%
  1867. The /PACKCODE linker option groups neighboring code segments together. When
  1868. used with the /F option, the /PACKCODE option greatly increases the number
  1869. of near calls that can be made to a function. This option can be followed
  1870. with a limit (expressed in bytes) at which to stop packing and to begin a
  1871. new group. Here is the syntax for the /PACKCODE option: ;/PACKCODE option  %@NL@%
  1872. %@NL@%
  1873. %@AS@%  /PACKCODE:number%@AE@%%@NL@%
  1874. %@NL@%
  1875. where %@AI@%number%@AE@% is an optional hexadecimal, octal, or decimal number that
  1876. specifies the limit for packing. The radix (octal, decimal, or hexadecimal)
  1877. is specified just as you would specify it to a C program.%@CR:C6A00010032 @%  %@NL@%
  1878. %@NL@%
  1879. %@AB@%Radix%@AE@%                             %@AB@%Rules for Specification%@AE@%
  1880. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1881. Octal                             Specify the octal number with a leading 
  1882.                                   0. You can only use the digits 0 through
  1883.                                   7 in an octal number. For example, 07777.
  1884.  
  1885. Decimal                           Specify the decimal number without a 
  1886.                                   leading 0. For example, 65530.
  1887.  
  1888. Hexadecimal                       Specify the hexadecimal number with a 
  1889.                                   leading 0x. For example, 0x3FFF.
  1890.  
  1891. If you omit the packing limit, the linker supplies a default value of 65,
  1892. 530.  %@NL@%
  1893. %@NL@%
  1894. The abbreviation for the /PACKCODE option is /PACKC.  %@NL@%
  1895. %@NL@%
  1896. %@NL@%
  1897. %@3@%%@CR:C6A00010033 @%%@AB@%1.6.3  Packing Data (/PACKDATA)%@AE@%%@EH@%%@NL@%
  1898. %@NL@%
  1899. The /PACKDATA option is analogous to the /PACKCODE option, except that it
  1900. groups together neighboring data segments instead of code segments. This
  1901. option is most useful when you have a large-model program that exceeds the
  1902. OS/2 limitation of 255 segments. By using /PACKDATA, you can group segments,
  1903. thereby reducing the total number OS/2 has to manage. Here is the syntax for
  1904. the /PACKDATA option:%@CR:C6A00010034 @%  %@NL@%
  1905. %@NL@%
  1906. %@AS@%  /PACKDATA:number%@AE@%%@NL@%
  1907. %@NL@%
  1908. where %@AI@%number%@AE@% is an optional hexadecimal, octal, or decimal number that
  1909. specifies the limit for packing. The radix (hexadecimal, octal, or decimal)
  1910. is specified just as you would specify it to a C program. For more
  1911. information on specifying hexadecimal, octal, or decimal numbers, see
  1912. Section 1.6.2 above.  %@NL@%
  1913. %@NL@%
  1914. If the packing limit is omitted, the linker supplies a default value of
  1915. 65,535 (0xFFFF).%@CR:C6A00010035 @%  %@NL@%
  1916. %@NL@%
  1917. The abbreviation for the /PACKDATA option is /PACKD.  %@NL@%
  1918. %@NL@%
  1919. %@NL@%
  1920. %@3@%%@CR:C6A00010036 @%%@AB@%1.6.4  Packing the Executable File (/EXEPACK)%@AE@%%@EH@%%@NL@%
  1921. %@NL@%
  1922. The executable file created by the compiler often contains sequences of
  1923. repeated bytes. You can remove these repeated sequences with the /EXEPACK
  1924. option. This decreases the size of the resulting executable file as well as
  1925. program load time.%@CR:C6A00010037 @%  %@NL@%
  1926. %@NL@%
  1927. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1928. %@AU@%WARNING%@AE@%%@NL@%
  1929. %@NL@%
  1930. Because the /EXEPACK option removes debug information from the executable
  1931. file, you should not use it with the /CODEVIEW option.%@NL@%
  1932. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1933. %@NL@%
  1934. %@NL@%
  1935. %@2@%%@CR:C6A00010038 @%%@AB@%1.7  Optimizing in Different Environments%@AE@%%@EH@%%@NL@%
  1936. %@NL@%
  1937. The environment in which you plan to use a program can have a bearing on the
  1938. types of optimizations that you should use.  %@NL@%
  1939. %@NL@%
  1940. %@NL@%
  1941. %@3@%%@CR:C6A00010039 @%%@AB@%1.7.1  Optimizing in DOS%@AE@%%@EH@%%@NL@%
  1942. %@NL@%
  1943. You need not take special precautions for programs written under DOS unless
  1944. you are writing a terminate-and-stay-resident (TSR) program. If an
  1945. interrupt-driven routine could modify a memory location in a program, you
  1946. should declare that variable %@AB@%volatile%@AE@%.  %@NL@%
  1947. %@NL@%
  1948. %@NL@%
  1949. %@3@%%@CR:C6A00010040 @%%@AB@%1.7.2  Optimizing in OS/2%@AE@%%@EH@%%@NL@%
  1950. %@NL@%
  1951. Many of the rules for interrupt routines apply to OS/2. If one thread can
  1952. modify variables in another thread, declare these variables as %@AB@%volatile%@AE@%.  %@NL@%
  1953. %@NL@%
  1954. %@NL@%
  1955. %@3@%%@CR:C6A00010041 @%%@AB@%1.7.3  Optimizing in Microsoft Windows(tm)%@AE@%%@EH@%%@NL@%
  1956. %@NL@%
  1957. Microsoft Windows(tm) can move segments dynamically. As a result of dynamic
  1958. heap compaction, pointers maintained in registers can be invalidated. The
  1959. /Ow option instructs the compiler that you will not be using aliases, but
  1960. that Windows might cause certain optimizations to be unsafe across function
  1961. calls.  %@NL@%
  1962. %@NL@%
  1963. If you are not using any aliases you must still use the /Ow option with
  1964. Windows programs. See Section 1.5.3, "Assuming No Aliasing (/Oa and /Ow),"
  1965. for more information.  %@NL@%
  1966. %@NL@%
  1967. %@NL@%
  1968. %@2@%%@CR:C6A00010042 @%%@AB@%1.8  Choosing Function-Calling Conventions%@AE@%%@EH@%%@NL@%
  1969. %@NL@%
  1970. In Microsoft C, version 6.0, functions can call other functions using three
  1971. different conventions. Note that, while no calling convention has been
  1972. defined as "standard," most C compilers use conventions similar to those
  1973. described here. The C calling convention requires the most object code to
  1974. set up, but it is the only calling convention that supports functions with
  1975. variable-length argument lists. The FORTRAN/Pascal calling convention is
  1976. more compact, but does not allow for variable-length argument lists. The
  1977. %@AB@%_fastcall%@AE@%, or register calling convention is the fastest of the three
  1978. calling conventions, but it does not support  variable-length argument lists
  1979. or mixed-language program interfaces.  %@NL@%
  1980. %@NL@%
  1981. %@NL@%
  1982. %@3@%%@CR:C6A00010043 @%%@AB@%1.8.1  The C Calling Convention (/Gd)%@AE@%%@EH@%%@NL@%
  1983. %@NL@%
  1984. Because C allows functions to have a variable number of parameters,
  1985. parameters must be pushed onto the stack from right to left. (If parameters
  1986. were pushed from left to right, it would be difficult for the compiler to
  1987. determine which parameter was first.) If you do not specify command-line
  1988. options that modify the function-calling convention, the C calling
  1989. convention is used; otherwise, the %@AB@%_cdecl%@AE@% keyword must be used before any
  1990. function using the C calling convention.%@CR:C6A00010044 @%%@CR:C6A00010045 @%%@CR:C6A00010046 @%  %@NL@%
  1991. %@NL@%
  1992. If, for example, you use the /Gr (register calling convention) option when
  1993. you compile, and the function %@AS@% add_two %@AE@% must have the C calling convention,
  1994. declare %@AS@% add_two %@AE@% as follows:  %@NL@%
  1995. %@NL@%
  1996. %@AS@%  int _cdecl add_two( int x, int y );%@AE@%%@NL@%
  1997. %@NL@%
  1998. %@NL@%
  1999. %@3@%%@CR:C6A00010047 @%%@AB@%1.8.2  The FORTRAN/Pascal Calling Convention (/Gc)%@AE@%%@EH@%%@NL@%
  2000. %@NL@%
  2001. Use the FORTRAN/Pascal calling convention for any functions declared with
  2002. either the %@AB@%_fortran%@AE@% or %@AB@%_pascal%@AE@% keywords. (The two keywords currently produce
  2003. identical results.) Parameters to these functions are always pushed on the
  2004. stack from left to right. While any function can be declared with the
  2005. FORTRAN/ Pascal convention, it is used primarily for prototypes to Pascal or
  2006. FORTRAN routines called from within C programs. This calling convention can
  2007. also produce smaller, faster programs.  %@NL@%
  2008. %@NL@%
  2009. The /Gc option (generate Pascal-style function calls) can be used to make
  2010. all functions in a file observe the FORTRAN/Pascal calling convention.  %@NL@%
  2011. %@NL@%
  2012. Note that C run-time library routines must still be called using C calling
  2013. conventions. Because these routines are declared using the %@AB@%_cdecl%@AE@% keyword
  2014. header files, you must include the appropriate header files in any program
  2015. using run-time library routines.  %@NL@%
  2016. %@NL@%
  2017. Functions with variable-length parameter lists (such as %@AB@%printf%@AE@%) cannot use
  2018. the FORTRAN/Pascal calling convention.  %@NL@%
  2019. %@NL@%
  2020. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2021. NOTE
  2022.  
  2023. %@AI@%The /ML, /MD, and /MT options cause all floating-point functions to be
  2024. %@AI@%declared as FORTRAN/Pascal. See Chapter 16, "Dynamic Linking with OS/2," for
  2025. %@AI@%more information.%@AE@%%@NL@%
  2026. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2027. %@NL@%
  2028. %@NL@%
  2029. %@3@%%@CR:C6A00010048 @%%@AB@%1.8.3  The Register Calling Convention (/Gr)%@AE@%%@EH@%%@NL@%
  2030. %@NL@%
  2031. You can decrease execution time if parameters to functions are passed in
  2032. registers rather than on the stack. Compiling with the /Gr command-line
  2033. option enables the register calling convention for an entire file. The
  2034. %@AB@%_fastcall%@AE@% keyword enables the register calling convention on a
  2035. function-by-function basis.  %@NL@%
  2036. %@NL@%
  2037. Because the 80%@AI@%x%@AE@%86 processor has a limited number of registers, only the
  2038. first three parameters are allocated to registers; the rest are passed using
  2039. the FORTRAN/Pascal calling convention. The register calling convention can
  2040. increase the speed of a program.%@CR:C6A00010049 @%%@CR:C6A00010050 @%%@CR:C6A00010051 @%  %@NL@%
  2041. %@NL@%
  2042. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2043. NOTE
  2044.  
  2045. %@AI@%The compiler allocates different registers for variables declared as
  2046. %@AB@%register %@AE@%%@AI@%and for passing arguments using the register calling convention.
  2047. %@AI@%This calling convention will not conflict with any register variables that
  2048. %@AI@%you may have declared.%@AE@%%@AE@%%@NL@%
  2049. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2050. %@NL@%
  2051. Exercise caution when using the register calling convention for any function
  2052. written in in-line assembly language. Your use of registers in
  2053. assembly-language could conflict with the compiler's use of registers for
  2054. storing parameters.  %@NL@%
  2055. %@NL@%
  2056. %@NL@%
  2057. %@3@%%@CR:C6A00010052 @%%@AB@%1.8.4  The _fastcall Calling Convention%@AE@%%@EH@%%@NL@%
  2058. %@NL@%
  2059. This section describes the details of the %@AB@%_fastcall%@AE@% calling convention. The
  2060. information is for the use of assembly-language programmers who are
  2061. interested in using either the in-line assembler or the Microsoft Macro
  2062. Assembler (MASM) to write functions declared as %@AB@%_fastcall%@AE@%. Functions
  2063. declared as %@AB@%_fastcall%@AE@% accept arguments in registers rather than on the
  2064. stack; functions declared as %@AB@%_cdecl%@AE@% or %@AB@%_pascal%@AE@% accept parameters only on the
  2065. stack.  %@NL@%
  2066. %@NL@%
  2067. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2068. %@AU@%WARNING%@AE@%%@NL@%
  2069. %@NL@%
  2070. The register usage documented here applies only to Microsoft C, version 6.0.
  2071. It may change in future releases of the compiler.%@NL@%
  2072. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2073. %@NL@%
  2074. %@NL@%
  2075. %@4@%%@AB@%Argument-Passing Convention%@AE@%%@EH@%%@NL@%
  2076. %@NL@%
  2077. The %@AB@%_fastcall%@AE@% calling convention is a "strongly typed" register calling
  2078. convention. This typing allows the compiler to generate better code by
  2079. passing arguments in registers that correspond to the data type you are
  2080. passing. Because the compiler chooses registers depending on the type of the
  2081. argument and not in a strict linear order, the calling program and called
  2082. function must agree on the types of the arguments in order to communicate
  2083. data correctly.  %@NL@%
  2084. %@NL@%
  2085. For each type of argument there is a list of register candidates. The
  2086. arguments are allocated to registers or, if no suitable register remains
  2087. unused, are pushed onto the stack left-to-right. Each argument is put in the
  2088. first register candidate that does not already contain an argument. Table
  2089. 1.3 shows the basic types and the register candidate list for each.  %@NL@%
  2090. %@NL@%
  2091. %@AB@%Table   %@AB@%1.3 Register Candidates%@AE@%%@AE@%
  2092.  
  2093. %@TH:  11   634 02 33 43 @%
  2094. %@AB@%Type%@AE@%                             Register Candidates
  2095. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2096. character                        AL, DL, BL
  2097. unsigned character               AL, DL, BL
  2098. integer                          AX, DX, BX
  2099. unsigned integer                 AX, DX, BX
  2100. long integer                     DX:AX
  2101. unsigned long integer            DX:AX
  2102. near pointer                     BX, AX, DX
  2103. far or huge pointer              passed on the stack
  2104. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2105. %@TE:  11   634 02 33 43 @%
  2106.  
  2107. All far and huge pointers are pushed on the stack, as are all structures,
  2108. unions, and floating-point types.%@CR:C6A00010053 @%  %@NL@%
  2109. %@NL@%
  2110. %@NL@%
  2111. %@4@%%@AB@%Return Value Convention%@AE@%%@EH@%%@NL@%
  2112. %@NL@%
  2113. The %@AB@%_fastcall%@AE@% return value convention is based on the size of the return
  2114. value, except with floating-point types. All floating point types are
  2115. returned on the top of the NDP stack. For more information about the NDP
  2116. stack and returning floating-point values, see Chapter 4, "Controlling
  2117. Floating-Point Math Operations." The following list shows how values 4 bytes
  2118. or smaller, including unions and structures, are returned from a %@AB@%_fastcall
  2119. %@AB@%%@AE@%function.  %@NL@%
  2120. %@NL@%
  2121. %@AB@%Size%@AE@%                              %@AB@%Return Convention%@AE@%
  2122. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2123. 1 Byte                            AL Register
  2124.  
  2125. 2 Bytes                           AX Register
  2126.  
  2127. 4 Bytes                           DX, AX Registers (for pointers, the 
  2128.                                   segment is returned in DX, the offset in
  2129.                                   AX; for long integers,
  2130.                                   the most-significant byte is returned in
  2131.                                   DX, leastsignificant byte in AX)
  2132.  
  2133. Note that the protocol for returning values 4 bytes or smaller is the same
  2134. as for functions declared as %@AB@%_cdecl%@AE@%. To return structures and unions larger
  2135. than 4 bytes, the calling program passes a hidden parameter as the last item
  2136. pushed. This parameter is a near pointer, implicitly SS-relative, to a
  2137. buffer in which the value is to be returned. A far pointer to
  2138. SS:%@AI@%hidden-param%@AE@% must be returned in DX:AX. This is the same convention for
  2139. returning structures as %@AB@%_pascal.%@AE@%%@CR:C6A00010054 @%  %@NL@%
  2140. %@NL@%
  2141. %@NL@%
  2142. %@4@%%@AB@%Stack Adjustment Convention%@AE@%%@EH@%%@NL@%
  2143. %@NL@%
  2144. Unlike functions declared as %@AB@%_cdecl%@AE@%, functions declared as %@AB@%_fastcall%@AE@% must
  2145. pop the arguments off the stack. The calling program does not adjust the
  2146. stack after function return.  %@NL@%
  2147. %@NL@%
  2148. %@NL@%
  2149. %@4@%%@AB@%Register Preservation Requirement%@AE@%%@EH@%%@NL@%
  2150. %@NL@%
  2151. All functions must preserve the DS, BP, SI, and DI registers. Your %@AB@%_fastcall%@AE@%
  2152. function can modify the values in AX, BX, CX, DX, and ES.  %@NL@%
  2153. %@NL@%
  2154. %@NL@%
  2155. %@4@%%@AB@%Function-Naming Convention%@AE@%%@EH@%%@NL@%
  2156. %@NL@%
  2157. The public name put into the object file for a function declared as
  2158. %@AB@%_fastcall%@AE@% is the name given by the user with a leading "at sign" (@). No
  2159. case translation is performed on the function name. The function declaration
  2160. %@NL@%
  2161. %@NL@%
  2162. %@AS@%  int _fastcall FCFunc( void );%@AE@%%@NL@%
  2163. %@NL@%
  2164. causes the compiler to place the public symbol %@AS@% @FCFunc %@AE@% in your object file
  2165. at every location %@AS@% FCFunc %@AE@% is referenced in your program.  %@NL@%
  2166. %@NL@%
  2167. If you do not declare the function as %@AB@%_fastcall%@AE@% in your C program, the
  2168. compiler assumes the default calling convention. The default is usually the
  2169. C calling convention but can be changed by the /Gc (Pascal Calling
  2170. Convention), /Gr (Register Calling Convention), or /Gd (C Calling
  2171. Convention) options. If the linker gives you an unresolved external
  2172. reference, you may have failed to declare an external %@AB@%_fastcall%@AE@% function
  2173. properly. For more information about calling conventions, see Chapter 12,
  2174. "Programming with Mixed Languages."%@CR:C6A00010055 @%  %@NL@%
  2175. %@NL@%
  2176. %@NL@%
  2177. %@NL@%
  2178. %@NL@%
  2179. %@NL@%
  2180. %@NL@%
  2181. %@CR:C6A00020001 @%%@1@%%@AB@%Chapter 2  Managing Memory%@AE@%%@EH@%%@NL@%
  2182. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2183. %@NL@%
  2184. When you develop advanced applications in Microsoft C, you must pay
  2185. attention to memory management─that is, how data and code are stored and
  2186. accessed in memory. A well-thought-out memory strategy will make your
  2187. programs run faster and occupy less memory.  %@NL@%
  2188. %@NL@%
  2189. You can follow one or more of these memory management strategies:  %@NL@%
  2190. %@NL@%
  2191. %@NL@%
  2192.   ■   Choose a standard memory model.%@NL@%
  2193. %@NL@%
  2194.   ■   Create a mixed-model program with the %@AB@%_near%@AE@%, %@AB@%_far%@AE@%, %@AB@%_huge%@AE@%, and %@AB@%_based%@AE@%
  2195.       keywords.%@NL@%
  2196. %@NL@%
  2197.   ■   Create your own customized memory model.%@NL@%
  2198. %@NL@%
  2199.   ■   Allocate memory as you need it with the %@AB@%malloc%@AE@% family of functions.%@NL@%
  2200. %@NL@%
  2201. %@NL@%
  2202. This chapter explains pointers, memory models (including the new tiny
  2203. model), variations such as custom memory models and mixed models, and based
  2204. pointers.  %@NL@%
  2205. %@NL@%
  2206. %@NL@%
  2207. %@2@%%@CR:C6A00020002 @%%@AB@%2.1  Pointer Sizes%@AE@%%@EH@%%@NL@%
  2208. %@NL@%
  2209. One of the strengths of the C language is that it allows you to use pointers
  2210. to directly access memory locations.  %@NL@%
  2211. %@NL@%
  2212. Every Microsoft C program has at least two parts: the code (function
  2213. definitions) and the data (variables and constants). As a program runs, it
  2214. refers to elements of the code or the data by their addresses. These
  2215. addresses can be stored in pointer variables.  %@NL@%
  2216. %@NL@%
  2217. Pointer variables can fit into 16 bits or 32 bits, depending on the distance
  2218. of the object to which they refer.  %@NL@%
  2219. %@NL@%
  2220. %@NL@%
  2221. %@3@%%@CR:C6A00020003 @%%@AB@%2.1.1  Pointers and 64K Segments%@AE@%%@EH@%%@NL@%
  2222. %@NL@%
  2223. IBM personal computers and compatibles use the Intel(R) 8086, 80186, 80286,
  2224. or 80386 processors (collectively called the 80%@AI@%x%@AE@%86 family). These processors
  2225. have a "segmented" architecture, which means they all have a mode that
  2226. treats memory as a series of segments, each of which occupies up to 64K of
  2227. memory. An offset from the base of the segment allows you to access
  2228. information within a given segment. Moving to a new segment requires
  2229. additional machine code.  %@NL@%
  2230. %@NL@%
  2231. %@AU@% A 16-bit pointer can address up to 65,536 locations.%@AE@%  %@NL@%
  2232. %@NL@%
  2233. The 64K limit is necessary because the 80%@AI@%x%@AE@%86 registers are 16 bits (2 bytes)
  2234. wide. A single register can address only 65,536 (64K) unique memory
  2235. locations.  %@NL@%
  2236. %@NL@%
  2237. A pointer variable that fully specifies a memory address needs 16 bits for
  2238. the segment location and another 16 bits for the offset within the segment,
  2239. a total of 32 bits. However, if you have several variables in the same
  2240. general area, your program can set the segment register once and treat the
  2241. pointers as smaller 16-bit quantities.  %@NL@%
  2242. %@NL@%
  2243. The 80%@AI@%x%@AE@%86 register CS holds the base for the code segment; the register DS
  2244. holds the base for the data segment. Two other segment registers are
  2245. available: the stack segment register (SS) and the extra segment register
  2246. (ES). (The 80386 has additional segment registers: FS and GS.)  %@NL@%
  2247. %@NL@%
  2248. %@NL@%
  2249. %@3@%%@CR:C6A00020004 @%%@AB@%2.1.2  Near Pointers%@AE@%%@EH@%%@NL@%
  2250. %@NL@%
  2251. If you don't explicitly specify a memory model, Microsoft C defaults to the
  2252. small model, which allots up to 64K for the code and another 64K for the
  2253. data (see Figure 2.1).  %@NL@%
  2254. %@NL@%
  2255. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  2256. %@NL@%
  2257. When a small-model program runs, the CS and DS segment registers never
  2258. change. All code pointers and all data pointers contain 16 bits because they
  2259. remain within the 64K range.  %@NL@%
  2260. %@NL@%
  2261. These 16-bit pointers to objects within a single 64K segment are called
  2262. "near pointers." Accessing a near object is called "near addressing."  %@NL@%
  2263. %@NL@%
  2264. %@NL@%
  2265. %@3@%%@CR:C6A00020005 @%%@AB@%2.1.3  Far Pointers%@AE@%%@EH@%%@NL@%
  2266. %@NL@%
  2267. If your program needs more than 64K for code or data, at least some of the
  2268. pointers must specify the memory segment, which means these pointers occupy
  2269. 32 bits instead of 16 bits.  %@NL@%
  2270. %@NL@%
  2271. These larger 32-bit pointers that can point anywhere in memory are called
  2272. "far pointers." Accessing a far object is called "far addressing."  %@NL@%
  2273. %@NL@%
  2274. %@AU@% Far pointers can address any location, but they are bigger and slower.%@AE@%  %@NL@%
  2275. %@NL@%
  2276. Far addressing has the advantage that your program can address any available
  2277. memory location─up to 640K in DOS or several megabytes in OS/2. The
  2278. disadvantages of the larger far pointers is that they take up more memory
  2279. (four bytes instead of two) and that any use of the pointers (assigning,
  2280. modifying, or otherwise accessing values) takes more time.  %@NL@%
  2281. %@NL@%
  2282. Allowing either code or data to expand beyond 64K makes your programs larger
  2283. and slower.  %@NL@%
  2284. %@NL@%
  2285. %@NL@%
  2286. %@3@%%@CR:C6A00020006 @%%@AB@%2.1.4  Huge Pointers%@AE@%%@EH@%%@NL@%
  2287. %@NL@%
  2288. A third type of pointer in Microsoft C is the "huge" pointer, which applies
  2289. only to data pointers. Code pointers cannot be declared as huge.  %@NL@%
  2290. %@NL@%
  2291. A huge address is similar to a far address in that both contain 32 bits,
  2292. made up of a segment value and an offset value. They differ only in the way
  2293. pointer arithmetic is performed.  %@NL@%
  2294. %@NL@%
  2295. For far pointers, Microsoft C assumes that code and data objects lie
  2296. completely within the segment in which they start, so pointer arithmetic
  2297. operates only on the offset portion of the address. Limiting the size of any
  2298. single item to 64K makes pointer arithmetic faster.  %@NL@%
  2299. %@NL@%
  2300. Huge pointers overcome this size limitation; pointer arithmetic is performed
  2301. on all 32 bits of the data item's address, thus allowing data items
  2302. referenced by huge pointers to span more than one segment. In this code
  2303. fragment,  %@NL@%
  2304. %@NL@%
  2305. %@AS@%  int _huge *hp;
  2306. %@AS@%  int _far *fp;
  2307. %@AS@%  .
  2308. %@AS@%  .
  2309. %@AS@%  .
  2310. %@AS@%  hp++;
  2311. %@AS@%  fp++;%@AE@%%@NL@%
  2312. %@NL@%
  2313. both %@AS@% hp %@AE@% and %@AS@% fp %@AE@% are incremented. The huge pointer is incremented as a
  2314. 32-bit value that represents the combined segment and offset. Only the
  2315. offset part of the far pointer (a 16-bit value) is incremented.  %@NL@%
  2316. %@NL@%
  2317. Extending the size of pointer arithmetic from 16 to 32 bits causes such
  2318. arithmetic to execute more slowly. You gain the use of larger arrays by
  2319. paying a price in execution speed.  %@NL@%
  2320. %@NL@%
  2321. %@NL@%
  2322. %@3@%%@CR:C6A00020007 @%%@AB@%2.1.5  Based Addressing%@AE@%%@EH@%%@NL@%
  2323. %@NL@%
  2324. When you declare near, far, and huge variables, the Microsoft C compiler and
  2325. linker automatically manage details such as allocating memory and keeping
  2326. track of segments.  %@NL@%
  2327. %@NL@%
  2328. A "based pointer" is a fourth kind of pointer that operates as a 16-bit
  2329. offset from a base that you specify. In this respect, based addressing
  2330. differs from near, far, or huge addressing; you're responsible for naming
  2331. the base, instead of letting the compiler decide.  %@NL@%
  2332. %@NL@%
  2333. Based pointers are new to version 6.0 of Microsoft C. They are explained in
  2334. more detail in Section 2.5, "Using Based Variables."  %@NL@%
  2335. %@NL@%
  2336. %@NL@%
  2337. %@2@%%@CR:C6A00020008 @%%@AB@%2.2  Selecting a Standard Memory Model%@AE@%%@EH@%%@NL@%
  2338. %@NL@%
  2339. If you want to choose one size for all pointers, there's no need to declare
  2340. each variable as near or far. Instead, you select a standard memory model
  2341. and your choice applies to all variables in the program.  %@NL@%
  2342. %@NL@%
  2343. One advantage of using standard memory models is simplicity. You specify the
  2344. way the compiler allocates storage for code and data only once.  %@NL@%
  2345. %@NL@%
  2346. %@AU@% A standard memory model assumes all pointers are the same size.%@AE@%  %@NL@%
  2347. %@NL@%
  2348. Another advantage is that the standard memory models do not require the use
  2349. of Microsoft-specific keywords such as %@AB@%_near%@AE@% and %@AB@%_far%@AE@%, so they are best for
  2350. writing code that is portable to other (non-DOS) systems.  %@NL@%
  2351. %@NL@%
  2352. The disadvantage of standard memory models is that, because they make global
  2353. assumptions about the environment, they do not always produce the most
  2354. efficient code.  %@NL@%
  2355. %@NL@%
  2356. %@NL@%
  2357. %@3@%%@CR:C6A00020009 @%%@AB@%2.2.1  The Six Standard Memory Models%@AE@%%@EH@%%@NL@%
  2358. %@NL@%
  2359. The six Microsoft C memory models are shown in Table 2.1.  %@NL@%
  2360. %@NL@%
  2361. %@AB@%Table 2.1  %@AB@%Memory Models %@AE@%%@AE@%
  2362.  
  2363. %@TH:  10   600 03 10 22 11 33 @%
  2364.           Maximum Total Memory  
  2365. Model     Code                  Data       Data Arrays
  2366. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2367. Tiny      <64K                  <64K       <64K
  2368. Small     64K                   64K        64K
  2369. Medium    No limit              64K        64K
  2370. Compact   64K                   No limit   64K
  2371. Large     No limit              No limit   64K
  2372. Huge      No limit              No limit   No limit
  2373. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2374. %@TE:  10   600 03 10 22 11 33 @%
  2375.  
  2376. The SETUP program creates the libraries that support the six standard memory
  2377. models.  %@NL@%
  2378. %@NL@%
  2379. When you choose one of the standard memory models, the compiler inserts the
  2380. name of the corresponding C run-time library in the object file so the
  2381. linker chooses it automatically. Each memory model has its own library,
  2382. except for the huge memory model (which uses the large-model library) and
  2383. the tiny model (which uses the small-model library).  %@NL@%
  2384. %@NL@%
  2385. %@NL@%
  2386. %@3@%%@CR:C6A00020010 @%%@AB@%2.2.2  Limitations on Code Size and Data Size%@AE@%%@EH@%%@NL@%
  2387. %@NL@%
  2388. When writing a program in Microsoft C, keep in mind two limitations that
  2389. apply to all six memory models:%@CR:C6A00020011 @%  %@NL@%
  2390. %@NL@%
  2391. %@NL@%
  2392.   ■   No single source module can generate 64K or more of code. You must
  2393.       break large programs into modules and link their individual .OBJ files
  2394.       to create the .EXE file.%@NL@%
  2395. %@NL@%
  2396.   ■   No single data item can exceed 64K unless it appears in a huge-model
  2397.       program or it has been declared with the %@AB@%_huge%@AE@% keyword.%@NL@%
  2398. %@NL@%
  2399. %@NL@%
  2400. %@NL@%
  2401. %@3@%%@CR:C6A00020012 @%%@AB@%2.2.3  The Tiny Memory Model%@AE@%%@EH@%%@NL@%
  2402. %@NL@%
  2403. The tiny memory model is new to Microsoft C. It resembles the small model
  2404. with three exceptions:%@CR:C6A00020013 @%%@CR:C6A00020014 @%  %@NL@%
  2405. %@NL@%
  2406. %@NL@%
  2407.   ■   The tiny model cannot exceed 64K per program (including both code and
  2408.       data). A small-model program, on the other hand, can occupy up to
  2409.       128K: 64K for code and 64K for data.%@NL@%
  2410. %@NL@%
  2411.   ■   The tiny model produces .COM, rather than .EXE, files. To produce .COM
  2412.       files, compile with the /AT option. Then link with the / TINY option
  2413.       and link in CRTCOM.OBJ.%@NL@%
  2414. %@NL@%
  2415.   ■   The tiny model applies to DOS only; it is not available in OS/2.%@NL@%
  2416. %@NL@%
  2417. %@NL@%
  2418. Although the tiny model imposes the most severe limits on code and data
  2419. size, it produces the smallest programs. The tiny memory model only offers a
  2420. load-time speed advantage over the small model; they both produce the
  2421. fastest programs.  %@NL@%
  2422. %@NL@%
  2423. %@NL@%
  2424. %@3@%%@CR:C6A00020015 @%%@AB@%2.2.4  The Huge Memory Model%@AE@%%@EH@%%@NL@%
  2425. %@NL@%
  2426. The huge memory model is nearly identical to the large model. The only
  2427. difference is that the huge model permits individual arrays to exceed 64K in
  2428. size. For example, an %@AB@%int%@AE@% uses two bytes, so an array of 40,000 integers,
  2429. occupying 80,000 bytes of memory, would be permitted in the huge model. All
  2430. other models limit each array, structure, or other data object to no more
  2431. than 64K.  %@NL@%
  2432. %@NL@%
  2433. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2434. NOTE
  2435. %@AI@%Automatic arrays cannot be declared huge. Only static arrays and arrays
  2436. %@AI@%occupying memory allocated by the %@AB@%halloc%@AE@%%@AI@% function can be huge.%@AE@%%@AE@%%@NL@%
  2437. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2438. %@NL@%
  2439. %@AU@% The huge model lifts  the limits on arrays.%@AE@%  %@NL@%
  2440. %@NL@%
  2441. Although the huge model lifts the limits on arrays, some size restrictions
  2442. do apply. To maintain efficient addressing, no individual array element is
  2443. allowed to cross a segment boundary. This has the following implications:  %@NL@%
  2444. %@NL@%
  2445. %@NL@%
  2446.   ■   No single element of an array can be larger than 64K. An array can be
  2447.       larger than 64K, but its individual elements cannot.%@NL@%
  2448. %@NL@%
  2449.   ■   For any array larger than 128K, all elements must have a size in bytes
  2450.       equal to a power of 2: 2 bytes, 4 bytes, 8 bytes, 16 bytes, and so on.
  2451.       If the array is 128K or smaller, its elements can be any size, up to
  2452.       and including 64K.%@NL@%
  2453. %@NL@%
  2454. %@NL@%
  2455. Pointer arithmetic changes within the huge model, as well. In particular,
  2456. the %@AB@%sizeof%@AE@% operator may return an incorrect value. The ANSI draft standard
  2457. for C defines the value returned by %@AB@%sizeof%@AE@% to be of type %@AB@%size_t%@AE@% (which, in
  2458. Microsoft C, is  %@NL@%
  2459. %@NL@%
  2460. an %@AB@%unsigned int%@AE@%). The size in bytes of a huge array is an %@AB@%unsigned long%@AE@%
  2461. value, however. To find the correct value, you must use a type cast:  %@NL@%
  2462. %@NL@%
  2463. %@AS@%  (unsigned long)sizeof(monster_array)%@AE@%%@NL@%
  2464. %@NL@%
  2465. Similarly, the C language defines the result of subtracting two pointers as
  2466. %@AB@%ptrdiff_t%@AE@% (a %@AB@%signed int%@AE@% in Microsoft C). Subtracting two huge pointers will
  2467. yield a %@AB@%long%@AE@% value. Microsoft C gives the correct result with the following
  2468. type cast:  %@NL@%
  2469. %@NL@%
  2470. %@AS@%  (long)(ptr1_huge - ptr2_huge)%@AE@%%@NL@%
  2471. %@NL@%
  2472. When you select huge model, all %@AB@%extern%@AE@% arrays are treated as %@AB@%_huge%@AE@%.
  2473. Operations on data declared as %@AB@%_huge%@AE@% can be less efficient than the same
  2474. operations on data declared as %@AB@%_far%@AE@%.  %@NL@%
  2475. %@NL@%
  2476. %@NL@%
  2477. %@3@%%@CR:C6A00020016 @%%@AB@%2.2.5  Null Pointers%@AE@%%@EH@%%@NL@%
  2478. %@NL@%
  2479. Within the medium and compact models, code pointers and data pointers differ
  2480. in size: one is 16 bits wide and the other is 32 bits wide. When using these
  2481. memory models, you should be careful in your use of the manifest constant
  2482. %@AB@%NULL%@AE@%.  %@NL@%
  2483. %@NL@%
  2484. %@AB@%%@AE@%NULL represents a null data pointer. The C include files define it as  %@NL@%
  2485. %@NL@%
  2486. %@AS@%  #define NULL ((void *) 0)%@AE@%%@NL@%
  2487. %@NL@%
  2488. %@AU@% There can be problems in models with different sizes of code and data
  2489. %@AU@%pointers.%@AE@%  %@NL@%
  2490. %@NL@%
  2491. In memory models where data pointers have the same size as code pointers,
  2492. the actual size of a null pointer doesn't matter. In memory models where
  2493. code and data pointers are different sizes, problems can occur. Consider
  2494. this example:  %@NL@%
  2495. %@NL@%
  2496. %@AS@%  void main()
  2497. %@AS@%  {
  2498. %@AS@%     func1( NULL );
  2499. %@AS@%     func2( NULL );
  2500. %@AS@%  }
  2501. %@AS@%  
  2502. %@AS@%  func1( char *dp )
  2503. %@AS@%  {
  2504. %@AS@%     .
  2505. %@AS@%     .
  2506. %@AS@%     .
  2507. %@AS@%  }
  2508. %@AS@%  
  2509. %@AS@%  func2( char (*fp)( void ) )
  2510. %@AS@%  {
  2511. %@AS@%     .
  2512. %@AS@%     .
  2513. %@AS@%     .
  2514. %@AS@%  }%@AE@%%@NL@%
  2515. %@NL@%
  2516. In the absence of function prototypes for %@AS@% func1 %@AE@% and %@AS@% func2%@AE@%, the compiler
  2517. always assumes that %@AB@%NULL%@AE@% refers to data and not code.  %@NL@%
  2518. %@NL@%
  2519. The example above works correctly in tiny, small, large, and huge models
  2520. because, in those models, a data pointer is the same size as a code pointer.
  2521. Under medium or compact model, however, %@AS@% main %@AE@% passes %@AB@% NULL%@AE@% to %@AS@% func2 %@AE@% as a
  2522. null data pointer rather than as a null code pointer (a pointer to a
  2523. function), which means the pointer is the wrong size.  %@NL@%
  2524. %@NL@%
  2525. To ensure that your code works properly in all models, declare each function
  2526. with a prototype. For example, before %@AS@% main%@AE@%, include these two lines:  %@NL@%
  2527. %@NL@%
  2528. %@AS@%  int func1( char *dp );
  2529. %@AS@%  int func2( char (*fp)( void ));%@AE@%%@NL@%
  2530. %@NL@%
  2531. If you add these prototypes to the example, the code works properly in all
  2532. memory models. Prototypes force the compiler to coerce code pointers to the
  2533. correct size. Prototypes also enable strong type-checking of parameters.  %@NL@%
  2534. %@NL@%
  2535. %@NL@%
  2536. %@3@%%@CR:C6A00020017 @%%@AB@%2.2.6  Specifying a Memory Model%@AE@%%@EH@%%@NL@%
  2537. %@NL@%
  2538. If you do not specify a memory model, Microsoft C defaults to the small
  2539. model, which is adequate for many small to mid-sized programs.  %@NL@%
  2540. %@NL@%
  2541. You can select a memory model from the Programmer's WorkBench or from the
  2542. command line.  %@NL@%
  2543. %@NL@%
  2544. %@NL@%
  2545. %@4@%%@AB@%Selecting from within PWB%@AE@%%@EH@%%@NL@%
  2546. %@NL@%
  2547. If you're compiling from the Programmer's WorkBench, open the Options menu
  2548. and choose C Global Build Options. The available memory models appear in the
  2549. upper left corner. Choose one of the six standard models or choose
  2550. Customized and type in the options for a customized model.  %@NL@%
  2551. %@NL@%
  2552. %@NL@%
  2553. %@4@%%@AB@%Selecting from the Command Line%@AE@%%@EH@%%@NL@%
  2554. %@NL@%
  2555. You can choose a memory model by including an option on the command line.
  2556. For example, to compile CLICK.C as a compact-model program, type this:  %@NL@%
  2557. %@NL@%
  2558. %@AS@%  CL /AC CLICK.C%@AE@%%@NL@%
  2559. %@NL@%
  2560. The /AC option selects the compact memory model. The six options and four
  2561. libraries are listed below:  %@NL@%
  2562. %@NL@%
  2563. %@AB@%Option%@AE@%                            %@AB@%Memory Model: Library%@AE@%
  2564. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2565. /AT                               Tiny Model: SLIBC%@AI@%xx%@AE@%.LIB (plus CRTCOM.OBJ)
  2566.  
  2567. /AS                               Small Model: SLIBC%@AI@%xx%@AE@%.LIB
  2568.  
  2569. /AM                               Medium Model: MLIBC%@AI@%xx%@AE@%.LIB
  2570.  
  2571. /AC                               Compact Model: CLIBC%@AI@%xx%@AE@%.LIB
  2572.  
  2573. /AL                               Large Model: LLIBC%@AI@%xx%@AE@%.LIB
  2574.  
  2575. /AH                               Huge Model: LLIBC%@AI@%xx%@AE@%.LIB
  2576.  
  2577. %@NL@%
  2578. %@2@%%@CR:C6A00020018 @%%@AB@%2.3  Mixing Memory Models%@AE@%%@EH@%%@NL@%
  2579. %@NL@%
  2580. In standard memory models, explained above, all data pointers are the same
  2581. size and all code pointers are the same size.  %@NL@%
  2582. %@NL@%
  2583. A mixed memory model selectively combines different types of pointers within
  2584. the same program. A mixed model extends the limits of a given memory model
  2585. while retaining its benefits.%@CR:C6A00020019 @%%@CR:C6A00020020 @%%@CR:C6A00020021 @%%@CR:C6A00020022 @%  %@NL@%
  2586. %@NL@%
  2587. %@AU@% A mixed memory model lets you mix near and far pointers.%@AE@%  %@NL@%
  2588. %@NL@%
  2589. For example, imagine a programming situation where you add an array to a
  2590. small-model program, pushing the data segment past the 64K limit.  %@NL@%
  2591. %@NL@%
  2592. You could solve the problem by moving up from the small to the compact
  2593. memory model. Doing so would bump all data pointers from two to four bytes.
  2594. The .EXE file would grow accordingly. Execution time would slow.  %@NL@%
  2595. %@NL@%
  2596. A second and perhaps better solution is to stay within the standard small
  2597. memory model, which uses near pointers, but to declare the new array as far.
  2598. You mix near pointers and far pointers, creating a mixed model.  %@NL@%
  2599. %@NL@%
  2600. Microsoft C lets you override the standard addressing convention for a given
  2601. memory model by specifying that certain items are %@AB@%_near%@AE@%, %@AB@%_far%@AE@%, %@AB@%_huge%@AE@%, or
  2602. %@AB@%_based%@AE@%. These keywords are not a standard part of the C language; they are
  2603. Microsoft extensions, meaningful only on systems that use 80%@AI@%x%@AE@%86
  2604. microprocessors. Using these keywords may affect the portability of your
  2605. code.  %@NL@%
  2606. %@NL@%
  2607. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2608. NOTE
  2609.  
  2610. %@AI@%Previous versions of the Microsoft C Compiler accepted the keywords %@AB@%near%@AE@%%@AI@%,
  2611. %@AI@%%@AE@%%@AI@%%@AB@%far%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%huge %@AE@%%@AE@%%@AI@%without an initial underscore. Since the ANSI draft standard
  2612. %@AI@%for C permits compiler implementors to reserve identifiers that begin with
  2613. %@AI@%underscores, an underscore was added to these keywords to mark them as
  2614. %@AI@%Microsoft-specific. To maintain compatibility with existing source code, the
  2615. %@AI@%compiler still recognizes the obsolescent versions of these keywords.%@AE@%%@AE@%%@NL@%
  2616. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2617. %@NL@%
  2618. You can compile a program in the small model, for example, but declare a
  2619. certain array to be %@AB@%_far%@AE@%. At run time, the address of that array occupies
  2620. four bytes. The program may slow slightly when accessing items in that
  2621. particular far array, but throughout the rest of the program, all addressing
  2622. would be near. Note that all pointers to elements of an array declared as
  2623. %@AB@%_far%@AE@% must also be declared as %@AB@%_far%@AE@%.  %@NL@%
  2624. %@NL@%
  2625. Table 2.2 lists the effects of these keywords on data pointers, code
  2626. pointers, and pointer arithmetic.  %@NL@%
  2627. %@NL@%
  2628. %@AB@%Table 2.2  %@AB@%Addressing Declared with Microsoft Keywords%@AE@%%@AE@%
  2629.  
  2630. %@TH:  35  1876 02 09 22 22 23 @%
  2631. Keyword  Data                  Code                  Arithmetic
  2632. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2633. %@AB@%_near%@AE@%    Data reside in        Functions reside in   16 bits
  2634.          default data          current code          
  2635.          segment; 16-bit       segment; 16-bit       
  2636.          addresses             addresses             
  2637.  
  2638. %@AB@%_far%@AE@%     Data can be anywhere  Functions can be      16 bits
  2639.          in memory, not        called from anywhere  
  2640.          necessarily in the    in memory; 32-bit     
  2641.          default data          addresses             
  2642.          segment; 32-bit                             
  2643.          addresses                                   
  2644.  
  2645. %@AB@%_huge%@AE@%    Data can be anywhere  Not applicable;       32 bits
  2646.          in memory, not        code cannot be         (data only)
  2647.          necessarily in the    declared %@AB@%_huge%@AE@%        
  2648.          default data segment.                        
  2649.          Individual data                             
  2650.          items (arrays) can                          
  2651.          exceed 64K in size;                         
  2652.          32-bit addresses                            
  2653.  
  2654. %@AB@%_based%@AE@%   Data can be anywhere  Not applicable;       16 bits
  2655.          in memory, not        code cannot be         (data only)
  2656.          necessarily in the    declared %@AB@%_based%@AE@%       
  2657.          default data                                
  2658.          segment; 16-bit                             
  2659.          addresses plus a                            
  2660.          known base provide                          
  2661.          the range of 32-bit                         
  2662.          addresses                                   
  2663.  
  2664. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2665.  
  2666. %@TE:  35  1876 02 09 22 22 23 @%
  2667.  
  2668. %@NL@%
  2669. %@3@%%@CR:C6A00020023 @%%@AB@%2.3.1  Pointer Problems%@AE@%%@EH@%%@NL@%
  2670. %@NL@%
  2671. When you declare items to be %@AB@%_near%@AE@%, %@AB@%_far%@AE@%, %@AB@%_huge%@AE@%, or %@AB@%_based%@AE@%, you can link
  2672. with a standard run-time library. Be aware, however, that in some cases, the
  2673. modified pointers will be incompatible with standard library functions.
  2674. Watch for these problems that affect pointers:%@CR:C6A00020024 @%%@CR:C6A00020025 @%%@CR:C6A00020026 @%%@CR:C6A00020027 @%  %@NL@%
  2675. %@NL@%
  2676. %@NL@%
  2677.   ■   A library function that expects a 16-bit pointer as an argument will
  2678.       not function properly with modified variables that occupy 32 bits. In
  2679.       other words, you can cast a near pointer to a far pointer, because it
  2680.       adds the segment value and maintains the integrity of the address. If
  2681.       you cast a far pointer to near, however, the compiler generates a
  2682.       warning message because the offset may not lie within the default data
  2683.       segment, in which case the original far address is  irretrievably
  2684.       lost.%@NL@%
  2685. %@NL@%
  2686.   ■   A library function that returns a pointer will return a pointer of the
  2687.       default size for the memory model. This is only a problem if you are
  2688.       assigning the return value to a pointer of a smaller size. For
  2689.       example, there may be difficulties if you compile with a model that
  2690.       selects far data pointers, but you have explicitly declared the
  2691.       variable to receive the return value %@AB@%_near%@AE@%.%@NL@%
  2692. %@NL@%
  2693. %@STUB@%      This warning does not apply to all functions. See Section B.2.8 in
  2694.       Appendix B for a list of model-independent string and memory functions
  2695.       such as %@AB@%_fstrcat%@AE@%, the far version of %@AB@%strcat%@AE@%.%@NL@%
  2696. %@NL@%
  2697.   ■   Based pointers pose a special problem. Based pointers are passed to
  2698.       other functions as is (without normalization). Certain functions
  2699.       expect to receive based pointers, but most do not. Therefore, in most
  2700.       cases, you must either explicitly cast a based pointer to a far
  2701.       pointer or make sure that all functions that receive based pointers
  2702.       are prototyped.%@NL@%
  2703. %@NL@%
  2704. %@NL@%
  2705. Some run-time library functions support near, far, huge, and based
  2706. variables. For example, %@AB@%halloc%@AE@% allocates memory for a huge data array.  %@NL@%
  2707. %@NL@%
  2708. You can always pass the value (but not the address) of a far item to a
  2709. small-model library routine. For example,  %@NL@%
  2710. %@NL@%
  2711. %@AS@%  /* Compile in small model */
  2712. %@AS@%  #include <stdio.h>
  2713. %@AS@%  long _far time_val;
  2714. %@AS@%  
  2715. %@AS@%  void main()
  2716. %@AS@%  {
  2717. %@AS@%     time( &time_val );             /* Illegal far address */
  2718. %@AS@%     printf( "%ld\n", time_val );   /* Legal value */
  2719. %@AS@%  }%@AE@%%@NL@%
  2720. %@NL@%
  2721. When you use a mixed memory model, you should include function prototypes
  2722. with argument-type lists to ensure that all pointer arguments are passed to
  2723. functions correctly.  %@NL@%
  2724. %@NL@%
  2725. %@NL@%
  2726. %@3@%%@CR:C6A00020028 @%%@AB@%2.3.2  Declaring Near, Far, Huge, and Based Variables%@AE@%%@EH@%%@NL@%
  2727. %@NL@%
  2728. The %@AB@%_near%@AE@%, %@AB@%_far%@AE@%, %@AB@%_huge%@AE@%, and %@AB@%_based%@AE@% keywords modify either objects or
  2729. pointers to objects. When using them to declare variables, keep these rules
  2730. in mind:%@CR:C6A00020029 @%%@CR:C6A00020030 @%%@CR:C6A00020031 @%%@CR:C6A00020032 @%  %@NL@%
  2731. %@NL@%
  2732. %@NL@%
  2733.   ■   The keyword always modifies the object or pointer immediately to its
  2734.       right. In complex declarations, think of the %@AB@%_far%@AE@% keyword and the item
  2735.       to its right as being a single unit. For example, in the case of the
  2736.       declaration%@NL@%
  2737. %@NL@%
  2738. %@STUB@%      %@AS@%char _far * _near *p;%@AE@%%@NL@%
  2739. %@NL@%
  2740. %@STUB@%      %@AS@%p %@AE@% is a near pointer to a far pointer to %@AB@%char%@AE@%, which resides in the
  2741.       default data segment for the memory model being used.%@NL@%
  2742. %@NL@%
  2743. %@STUB@%      By contrast, the declaration%@NL@%
  2744. %@NL@%
  2745. %@STUB@%      %@AS@%char _far * _near p;%@AE@%%@NL@%
  2746. %@NL@%
  2747. %@STUB@%      is a far pointer to %@AB@%char%@AE@% that will always be stored in DGROUP,
  2748.       regardless of the memory model being used.%@NL@%
  2749. %@NL@%
  2750.   ■   If the item immediately to the right of the keyword is an identifier,
  2751.       the keyword determines whether the item will be allocated in the
  2752.       default data segment (%@AB@% _near%@AE@%) or a separate data segment (%@AB@% _far%@AE@%,
  2753.       %@AB@%_huge%@AE@%, or %@AB@%_based%@AE@%). For example,%@NL@%
  2754. %@NL@%
  2755. %@STUB@%      %@AS@%char _far a;%@AE@%%@NL@%
  2756. %@NL@%
  2757. %@STUB@%      allocates %@AS@% a %@AE@% as an item of type %@AB@%char%@AE@% with a %@AB@%_far%@AE@% address.%@NL@%
  2758. %@NL@%
  2759.   ■   If the item immediately to the right of the keyword is a pointer, the
  2760.       keyword determines whether the pointer will hold a near address (16
  2761.       bits), a based address (16 bits), a far address (32 bits), or a huge
  2762.       address (also 32 bits). For example,%@NL@%
  2763. %@NL@%
  2764. %@STUB@%      %@AS@%char _huge *p;%@AE@%%@NL@%
  2765. %@NL@%
  2766. %@STUB@%      allocates %@AS@% p %@AE@% as a huge pointer (32 bits) to an item of type %@AB@%char%@AE@%. Any
  2767.       arithmetic performed on the huge pointer %@AS@% p %@AE@% will affect all 32 bits.
  2768.       That is, the instruction %@AS@% p++ %@AE@% increments the pointer as a 32-bit
  2769.       entity.%@NL@%
  2770. %@NL@%
  2771. %@NL@%
  2772. %@NL@%
  2773. %@3@%%@CR:C6A00020033 @%%@AB@%2.3.3  Declaring Near and Far Functions%@AE@%%@EH@%%@NL@%
  2774. %@NL@%
  2775. You cannot declare functions as %@AB@%_huge%@AE@% or %@AB@%_based%@AE@%. The rules for using the
  2776. %@AB@%_near%@AE@% and %@AB@%_far%@AE@% keywords for functions are similar to those for using them
  2777. with data:  %@NL@%
  2778. %@NL@%
  2779. %@NL@%
  2780.   ■   The keyword always modifies the function or pointer immediately to its
  2781.       right.%@NL@%
  2782. %@NL@%
  2783.   ■   If the item immediately to the right of the keyword is a function, the
  2784.       keyword determines whether the function will be allocated as near or
  2785.       far. For example,%@NL@%
  2786. %@NL@%
  2787. %@STUB@%      %@AS@%char _far fun();%@AE@%%@NL@%
  2788. %@NL@%
  2789. %@STUB@%      defines %@AS@% fun %@AE@% as a function with a 32-bit address that returns a %@AB@%char%@AE@%.
  2790.       The function may be located in near memory or far memory, but it is
  2791.       called with the full 32-bit address. The %@AB@%_far%@AE@% keyword applies to the
  2792.       function, not to the return type.%@NL@%
  2793. %@NL@%
  2794.   ■   If the item immediately to the right of the keyword is a pointer to a
  2795.       function, the keyword determines whether the function will be called
  2796.       using a near (16-bit) or far (32-bit) address. For example,%@NL@%
  2797. %@NL@%
  2798. %@STUB@%      %@AS@%char (_far *pfun)( );%@AE@%%@NL@%
  2799. %@NL@%
  2800. %@STUB@%      defines %@AS@% pfun %@AE@% as a far pointer (32 bits) to a function returning type
  2801.       %@AB@%char%@AE@%.%@NL@%
  2802. %@NL@%
  2803.   ■   Function declarations must match function definitions.%@NL@%
  2804. %@NL@%
  2805.   ■   The %@AB@%_huge%@AE@% and %@AB@%_based%@AE@% keywords do not apply to functions. That is, a
  2806.       function cannot be huge (larger than 64K) or based. A function can
  2807.       return a huge data pointer to the calling function. A function can
  2808.       return a based pointer unless it is a pointer based on %@AB@%_self%@AE@% (see
  2809.       Section 2.5.2, "Declaring Based Variables").%@NL@%
  2810. %@NL@%
  2811. %@NL@%
  2812. The example below declares %@AS@% fun1 %@AE@% as a far function returning type %@AB@%char%@AE@%:  %@NL@%
  2813. %@NL@%
  2814. %@AS@%  char _far fun1(void);              /* small model */
  2815. %@AS@%  char _far fun(void)
  2816. %@AS@%  {
  2817. %@AS@%      .
  2818. %@AS@%      .
  2819. %@AS@%      .
  2820. %@AS@%  }%@AE@%%@NL@%
  2821. %@NL@%
  2822. Here, the %@AS@% fun2 %@AE@% function is a near function that returns a far pointer to
  2823. type %@AB@%char%@AE@%:  %@NL@%
  2824. %@NL@%
  2825. %@AS@%  char _far * _near fun2( );        /* large model */
  2826. %@AS@%  char _far * _near fun( )
  2827. %@AS@%  {
  2828. %@AS@%      .
  2829. %@AS@%      .
  2830. %@AS@%      .
  2831. %@AS@%  }%@AE@%%@NL@%
  2832. %@NL@%
  2833. The example below declares %@AS@% pfun %@AE@% as a far pointer to a function that has an
  2834. %@AB@%int%@AE@% return type, assigns the address of %@AB@%printf%@AE@% to %@AS@% pfun%@AE@%, and prints "Hello
  2835. world." twice.  %@NL@%
  2836. %@NL@%
  2837. %@AS@%  /* Compile in medium, large, or huge model */
  2838. %@AS@%  
  2839. %@AS@%  #include <stdio.h>
  2840. %@AS@%  int (_far *pfun)( char *, ... );
  2841. %@AS@%  
  2842. %@AS@%  void main()
  2843. %@AS@%  {
  2844. %@AS@%       pfun = printf;
  2845. %@AS@%       pfun( "Hello world.\n" );
  2846. %@AS@%       (*pfun)( "Hello world.\n" );
  2847. %@AS@%  }%@AE@%%@NL@%
  2848. %@NL@%
  2849. %@NL@%
  2850. %@3@%%@CR:C6A00020034 @%%@AB@%2.3.4  Pointer Conversions%@AE@%%@EH@%%@NL@%
  2851. %@NL@%
  2852. Passing near or far pointers as arguments to functions can cause automatic
  2853. conversions in the size of the pointer argument. Passing a pointer to an
  2854. unprototyped function forces the pointer size to the larger of the following
  2855. two sizes:  %@NL@%
  2856. %@NL@%
  2857. %@NL@%
  2858.   ■   The default pointer size for that type, as defined by the memory model
  2859.       selected during compilation.%@NL@%
  2860. %@NL@%
  2861. %@STUB@%      For example, in medium-model programs, data pointer arguments are near
  2862.       by default, and code pointer arguments are far by default.%@NL@%
  2863. %@NL@%
  2864.   ■   The size of the type of the argument.%@NL@%
  2865. %@NL@%
  2866. %@NL@%
  2867. Note that if you supply a based pointer as an argument to a function and do
  2868. not specifically cast it to a far pointer type, a 16-bit offset from the
  2869. base segment is passed.  %@NL@%
  2870. %@NL@%
  2871. %@AU@% Function prototypes prevent problems that may occur in mixed memory models.%@AE@%
  2872. %@NL@%
  2873. %@NL@%
  2874. If you provide a function prototype with complete argument types, the
  2875. compiler performs type-checking and enforces the conversion of actual
  2876. arguments to the declared type of the corresponding formal argument.
  2877. However, if no declaration is present or the argument-type list is empty,
  2878. the compiler will convert nonbased pointer arguments automatically to the
  2879. default type or the type of the argument, whichever is larger. To avoid
  2880. mismatched arguments, always use a prototype with the argument types.  %@NL@%
  2881. %@NL@%
  2882. For example, the following program produces unexpected results in
  2883. compact-model, large-model, or huge-model programs.  %@NL@%
  2884. %@NL@%
  2885. %@AS@%  void main( )
  2886. %@AS@%  {
  2887. %@AS@%      int _near *x;
  2888. %@AS@%     char _far *y;
  2889. %@AS@%     int z = 1;
  2890. %@AS@%  
  2891. %@AS@%     test_fun( x, y, z );   /* x is coerced to far
  2892. %@AS@%                                   pointer in compact,
  2893. %@AS@%                                   large, or huge model */
  2894. %@AS@%  }
  2895. %@AS@%  
  2896. %@AS@%  int test_fun( int _near *ptr1, char _far *ptr2, int a)
  2897. %@AS@%  {
  2898. %@AS@%      printf("Value of a = %d\n", a);
  2899. %@AS@%  }%@AE@%%@NL@%
  2900. %@NL@%
  2901. If the preceding example is compiled as a tiny, small, or medium program,
  2902. the size of %@AS@% x %@AE@% is 16 bits, the size of %@AS@% y %@AE@% is 32 bits, and the value
  2903. printed for %@AS@% a %@AE@% is 1.  %@NL@%
  2904. %@NL@%
  2905. However, if the example is compiled in compact, large, or huge model, both %@AS@%
  2906. %@AS@%x %@AE@% and %@AS@% y %@AE@% are automatically converted to far pointers when they are passed
  2907. to %@AS@% test_fun%@AE@%. Since %@AS@% ptr1%@AE@%, the first parameter of %@AS@% test_fun%@AE@%, is defined as a
  2908. near pointer argument, it takes only 16 bits of the 32 bits passed to it.
  2909. The next parameter, %@AS@% ptr2%@AE@%, takes the remaining 16 bits passed to %@AS@% ptr1%@AE@%, plus
  2910. 16 bits of the 32 bits passed to it. Finally, the third parameter, %@AS@% a%@AE@%, takes
  2911. the leftover 16 bits from %@AS@% ptr2%@AE@%, instead of the value of %@AS@% z %@AE@% in the %@AB@%main%@AE@%
  2912. function.  %@NL@%
  2913. %@NL@%
  2914. This shifting process does not generate an error message, because both the
  2915. function call and the function definition are legal. In this case the
  2916. program does not work as intended, however, since the value assigned to %@AS@% a %@AE@%
  2917. is not the value intended.  %@NL@%
  2918. %@NL@%
  2919. To pass %@AS@% ptr1 %@AE@% as a near pointer, you should include a function prototype
  2920. that specifically declares this argument for %@AS@% test_fun %@AE@% as a near pointer,
  2921. as shown below:  %@NL@%
  2922. %@NL@%
  2923. %@AS@%  /* First, prototype test_fun so the compiler
  2924. %@AS@%  * knows in advance about the near pointer argument:
  2925. %@AS@%  */
  2926. %@AS@%  int test_fun (int _near*, char _far *, int);
  2927. %@AS@%  
  2928. %@AS@%  main ( )
  2929. %@AS@%  {
  2930. %@AS@%     int _near *x;
  2931. %@AS@%     char _far *y;
  2932. %@AS@%     int z = 1;
  2933. %@AS@%  
  2934. %@AS@%     test_fun ( x, y, z );    /* now, x is not coerced
  2935. %@AS@%                              * to a far pointer; it is
  2936. %@AS@%                              * passed as a near pointer,
  2937. %@AS@%                              * no matter which memory
  2938. %@AS@%                              * model is used
  2939. %@AS@%                              */
  2940. %@AS@%  }
  2941. %@AS@%  
  2942. %@AS@%  int test_fun ( int _near *ptr1, char _far *ptr2, int a)
  2943. %@AS@%  {
  2944. %@AS@%     printf ( "Value of a = %d\n", a );
  2945. %@AS@%  }%@AE@%%@NL@%
  2946. %@NL@%
  2947. %@NL@%
  2948. %@2@%%@CR:C6A00020035 @%%@AB@%2.4  Customizing Memory Models%@AE@%%@EH@%%@NL@%
  2949. %@NL@%
  2950. A third way to manage memory is to combine different features from standard
  2951. memory models to create your own customized memory model. You should have a
  2952. thorough understanding of C memory models and the architecture of 80%@AI@%x%@AE@%86
  2953. processors before creating your own nonstandard memory models.  %@NL@%
  2954. %@NL@%
  2955. %@AU@% In a customized model, you select the size of code pointers and data
  2956. %@AU@%pointers.%@AE@%  %@NL@%
  2957. %@NL@%
  2958. The /A%@AI@%string%@AE@% option lets you change the attributes of the standard memory
  2959. models to create your own memory models. The three letters in %@AI@%string%@AE@%
  2960. correspond to the code pointer size, the data pointer size, and the stack
  2961. and data segment setup, respectively. Because the letter allowed in each
  2962. field is unique to that field, you can give the letters in any order after
  2963. /A. All three letters must be present.  %@NL@%
  2964. %@NL@%
  2965. The standard memory-model options (/AT, /AS, /AM, /AC, /AL, and /AH) can be
  2966. specified in the /A%@AI@%string%@AE@% form. As an example of how to construct memory
  2967. models, the standard memory-model options are listed below with their
  2968. /A%@AI@%string%@AE@% equivalents:  %@NL@%
  2969. %@NL@%
  2970. %@AB@%Standard%@AE@%                          %@AB@%Custom Equivalent%@AE@%
  2971. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2972. /AT                               /Asnd
  2973.  
  2974. /AS                               /Asnd
  2975.  
  2976. /AM                               /Alnd
  2977.  
  2978. /AC                               /Asfd
  2979.  
  2980. /AL                               /Alfd
  2981.  
  2982. /AH                               /Alhd
  2983.  
  2984. For example, you might want to create a huge-compact model. This model would
  2985. allow huge data items but only one code segment. The option for specifying
  2986. this model would be /Ashd.  %@NL@%
  2987. %@NL@%
  2988. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2989. NOTE
  2990.  
  2991. %@AI@%Tiny model is identical to small model except that it causes the linker to
  2992. %@AI@%search for CRTCOM.LIB. The executable file generated when you specify tiny
  2993. %@AI@%model is a .COM file rather than a .EXE.%@AE@%%@NL@%
  2994. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2995. %@NL@%
  2996. %@NL@%
  2997. %@3@%%@CR:C6A00020036 @%%@AB@%2.4.1  Setting a Size for Code Pointers%@AE@%%@EH@%%@NL@%
  2998. %@NL@%
  2999. Within a custom memory model, you choose whether code pointers are short or
  3000. long:  %@NL@%
  3001. %@NL@%
  3002. %@AB@%Option%@AE@%                            %@AB@%Size%@AE@%
  3003. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3004. /As%@AI@%xx%@AE@%                             Short (near) code pointers
  3005.  
  3006. /Al%@AI@%xx%@AE@%                             Long (far) code pointers
  3007.  
  3008. The /As (short) option tells the compiler to generate near 16-bit pointers
  3009. and addresses for all functions. This is the default for tiny-, small-, and
  3010. compact-model programs.  %@NL@%
  3011. %@NL@%
  3012. The /Al (long) option means that far 32-bit pointers and addresses are used
  3013. to address all functions. Far pointers are the default for medium-, large-,
  3014. and huge-model programs.  %@NL@%
  3015. %@NL@%
  3016. %@NL@%
  3017. %@3@%%@CR:C6A00020037 @%%@AB@%2.4.2  Setting a Size for Data Pointers%@AE@%%@EH@%%@NL@%
  3018. %@NL@%
  3019. Data pointers can be near, far, or huge:  %@NL@%
  3020. %@NL@%
  3021. %@AB@%Option%@AE@%                            %@AB@%Size%@AE@%
  3022. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3023. /A%@AI@%x%@AE@%n%@AI@%x%@AE@%                             Near data pointers
  3024.  
  3025. /A%@AI@%x%@AE@%f%@AI@%x%@AE@%                             Far data pointers
  3026.  
  3027. /A%@AI@%x%@AE@%h%@AI@%x%@AE@%                             Huge data pointers
  3028.  
  3029. The /An (near) option tells the compiler to use 16-bit pointers and
  3030. addresses for all data. This is the default for tiny-, small-, and
  3031. medium-model programs.  %@NL@%
  3032. %@NL@%
  3033. The /Af (far) option specifies that all data pointers and addresses are 32
  3034. bits. This is the default for compact- and large-model programs.  %@NL@%
  3035. %@NL@%
  3036. The /Ah (huge) option specifies that all data pointers and addresses are far
  3037. (32-bit) and that arrays are permitted to extend beyond a 64K segment. This
  3038. is the default for huge-model programs.  %@NL@%
  3039. %@NL@%
  3040. With far data pointers, no single data item can be larger than a segment
  3041. (64K) because address arithmetic is performed only on 16 bits (the offset
  3042. portion) of the address. When huge data pointers are used, individual data
  3043. items can be larger than a segment (64K) because address arithmetic is
  3044. performed on both the segment and the offset.  %@NL@%
  3045. %@NL@%
  3046. %@NL@%
  3047. %@3@%%@CR:C6A00020038 @%%@AB@%2.4.3  Setting Up Segments%@AE@%%@EH@%%@NL@%
  3048. %@NL@%
  3049. Within a customized model, you can choose to make the stack segment (SS)
  3050. equal the data segment (DS), in which case they overlap:%@CR:C6A00020039 @%  %@NL@%
  3051. %@NL@%
  3052. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  3053. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3054. /A%@AI@%xx%@AE@%d                             SS == DS
  3055.  
  3056. /A«%@AI@%xx%@AE@%»u                           SS != DS; DS reloaded on function entry
  3057.  
  3058. /A«%@AI@%xx%@AE@%»w                           SS != DS; DS not reloaded on function 
  3059.                                   entry
  3060.  
  3061. %@NL@%
  3062. %@4@%%@AB@%Segment Setup Option /Ad%@AE@%%@EH@%%@NL@%
  3063. %@NL@%
  3064. The option /Ad tells the compiler that the segment addresses stored in the
  3065. SS and DS registers are equal. The stack segment and the default data
  3066. segment are combined into a single segment. This is the default for all
  3067. standard-model programs. In small- and medium-model programs, the stack plus
  3068. all data must occupy less than 64K; thus, any data item is accessed with
  3069. only a 16-bit offset from the segment address in the SS and DS registers.  %@NL@%
  3070. %@NL@%
  3071. In compact-, large-, and huge-model programs, initialized global and static
  3072. data are placed in the default data segment up to a certain threshold. The
  3073. address of this segment is stored in the DS and SS registers. All pointers
  3074. to data, including pointers to local data (the stack), are full 32-bit
  3075. addresses. This is important to remember when passing pointers as arguments
  3076. in multiple-segment programs. Although you may have more than 64K of total
  3077. data in these models, no more than 64K of data can occupy the default
  3078. segment. The /Gt and /ND options control allocation of items in the default
  3079. data segment if a program exceeds this limit.  %@NL@%
  3080. %@NL@%
  3081. %@NL@%
  3082. %@4@%%@AB@%Segment Setup Option /Au%@AE@%%@EH@%%@NL@%
  3083. %@NL@%
  3084. The option /Au tells the compiler that the stack segment does not
  3085. necessarily coincide with the data segment. In addition, it adds the %@AB@%_loadds%@AE@%
  3086. attribute to all functions within a module, forcing the compiler to generate
  3087. code to load the DS register with the correct value prior to entering the
  3088. function body. Combine the /ND option with /Au to name data segments other
  3089. than the default. When /Au is combined with /ND, the address in the DS
  3090. register is saved upon entry to each function, and the new DS value for the
  3091. module in which the function was defined is loaded into the register. The
  3092. previous DS value is restored on exit from the function. Therefore, only one
  3093. data segment is accessible at any given time. The /ND option lets you
  3094. combine these segments into a single segment.  %@NL@%
  3095. %@NL@%
  3096. If a standard memory-model option precedes it on the command line, the /Au
  3097. option can be specified without any letters indicating data pointer or code
  3098. pointer sizes. The program uses a standard memory model, but different
  3099. segments are set up for the stack and data segments.  %@NL@%
  3100. %@NL@%
  3101. The /Au option is useful for OS/2 or Microsoft Windows dynamic-link
  3102. libraries (DLLs), since it forces DS to be loaded on entry to each function.
  3103. It is also useful for writing extensions to the Programmer's WorkBench. This
  3104. is a costly operation, however, so consider using the /Aw option.  %@NL@%
  3105. %@NL@%
  3106. %@NL@%
  3107. %@4@%%@AB@%Segment Setup Option /Aw%@AE@%%@EH@%%@NL@%
  3108. %@NL@%
  3109. The option /Aw, like /Au, causes the compiler to assume that the stack
  3110. segment is separate from the data segment. The compiler does not
  3111. automatically load the DS register at each function entry point. The /Aw
  3112. option is useful in creating applications that interface with an operating
  3113. system or with a program running at the operating-system level. The
  3114. operating system or the program running under the operating system actually
  3115. receives the data intended for the application program and places that data
  3116. in a segment; then the operating system or program must load the DS register
  3117. with the segment address for the application program.  %@NL@%
  3118. %@NL@%
  3119. As with the /Au option, the /Aw option can be specified without data pointer
  3120. and code pointer letters if a standard memory-model option precedes it on
  3121. the command line. In such a case, the program uses the specified memory
  3122. model just as with /Au, but the DS register is not reloaded at each function
  3123. entry point.  %@NL@%
  3124. %@NL@%
  3125. Even though /Au and /Aw indicate that the stack may be in a separate
  3126. segment, the stack's size is still fixed at the default size unless this is
  3127. overridden with the /F compiler option or the /STACK linker option.  %@NL@%
  3128. %@NL@%
  3129. The /Aw option is useful for writing OS/2 and Microsoft Windows dynamic-link
  3130. libraries (DLLs), but care must be taken when it is used. Declare all entry
  3131. points to the dynamic-link library as %@AB@%_loadds%@AE@% to force DS to be loaded on
  3132. entry to the function (exactly like the /Au option). The other functions
  3133. will then be more efficient, though, because they will not have to perform
  3134. redundant loads of the DS register. For example,  %@NL@%
  3135. %@NL@%
  3136. %@AS@%  _export _loadds _far pascal LibFunc( void )
  3137. %@AS@%  {
  3138. %@AS@%      .
  3139. %@AS@%      .
  3140. %@AS@%      .
  3141. %@AS@%      HelperFunc(); }
  3142. %@AS@%  
  3143. %@AS@%  HelperFunc( void )
  3144. %@AS@%  {
  3145. %@AS@%      .
  3146. %@AS@%      .
  3147. %@AS@%      .
  3148. %@AS@%  }%@AE@%%@NL@%
  3149. %@NL@%
  3150. The library entry point, %@AS@% LibFunc%@AE@%, is declared as %@AB@%_loadds%@AE@% to force the DS
  3151. register to be loaded on entry. The function %@AS@% HelperFunc%@AE@%, which is private
  3152. to the dynamic-link library, is declared as a normal C function. Since it
  3153. cannot be called from outside of the module, %@AS@% HelperFunc %@AE@% does not need to
  3154. reload DS.  %@NL@%
  3155. %@NL@%
  3156. If you choose one of the options that specifies that the stack segment is
  3157. not equal to the data segment (SS != DS), you cannot pass the address of
  3158. frame variables as arguments to functions that take near pointers. That is,
  3159. in tiny, small, and medium models, you cannot pass the address of a local
  3160. variable (which is allocated on the stack) as an argument, because the
  3161. receiving function will assume the pointer is relative to the data segment.
  3162. However, the receiving function could solve this problem by declaring the
  3163. pointer to be the following:  %@NL@%
  3164. %@NL@%
  3165. %@AS@%  based(_segname("_STACK"))%@AE@%%@NL@%
  3166. %@NL@%
  3167. Another solution would be to cast the pointer to a far pointer in both
  3168. locations as follows:  %@NL@%
  3169. %@NL@%
  3170. %@AS@%  /* Call func with an explicit cast to far */
  3171. %@AS@%  func( (char far *)frame_var );
  3172. %@AS@%  .
  3173. %@AS@%  .
  3174. %@AS@%  .
  3175. %@AS@%  void func( char far *formal_var )%@AE@%%@NL@%
  3176. %@NL@%
  3177. %@NL@%
  3178. %@3@%%@CR:C6A00020040 @%%@AB@%2.4.4  Library Support for Customized Memory Models%@AE@%%@EH@%%@NL@%
  3179. %@NL@%
  3180. Most C programs make function calls to the routines in the C run-time
  3181. library. When you write mixed-model programs, you are responsible for
  3182. determining which library (if any) is suitable for your program and for
  3183. ensuring that the appropriate library is linked. Table 2.3 shows the
  3184. libraries from which to extract the start-up routine for each customized
  3185. memory model.  %@NL@%
  3186. %@NL@%
  3187. %@AB@%Table 2.3  %@AB@%Start-Up Routines for Customized Memory Models%@AE@%%@AE@%
  3188.  
  3189. %@TH:   7   736 02 49 27 @%
  3190. %@AB@%Memory-Model%@AE@% %@AB@%Option%@AE@%                              %@AB@%From Library%@AE@%
  3191. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3192. /Asn%@AI@%x%@AE@%; /AS plus /A%@AI@%x %@AE@%                             SLIBC%@AI@%f%@AE@%.LIB
  3193. /Asf%@AI@%x%@AE@%; /Ash%@AI@%x%@AE@%; /AC plus /A%@AI@%x%@AE@%                       CLIBC%@AI@%f%@AE@%.LIB
  3194. /Aln%@AI@%x%@AE@%; /AM plus /A%@AI@%x%@AE@%                              MLIBC%@AI@%f%@AE@%.LIB
  3195. /Alf%@AI@%x%@AE@%; /Alh%@AI@%x%@AE@%; /AL plus /A%@AI@%x%@AE@%; /AH plus /A%@AI@%x %@AE@%        LLIBC%@AI@%f%@AE@%.LIB
  3196. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3197. %@TE:   7   736 02 49 27 @%
  3198.  
  3199. The /A%@AI@%x%@AE@% option represents either /Au or /Aw. In the library names, %@AI@% f%@AE@% is
  3200. either E (emulator library), 7 (8087/80287 library), or A (alternate math
  3201. library).  %@NL@%
  3202. %@NL@%
  3203. %@NL@%
  3204. %@3@%%@CR:C6A00020041 @%%@AB@%2.4.5  Setting the Data Threshold%@AE@%%@EH@%%@NL@%
  3205. %@NL@%
  3206. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  3207. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3208. /Gt«%@AI@%number%@AE@%»                       Sets the threshold
  3209.  
  3210. The /Gt option causes all data items whose size is greater than to %@AI@%number%@AE@%
  3211. bytes to be allocated to a new data segment. When %@AI@%number%@AE@% is specified, it
  3212. must follow the /Gt option immediately, with no intervening spaces. When
  3213. %@AI@%number%@AE@% is omitted, the default threshold value is 256. When the /Gt option
  3214. is omitted, the default threshold value is 32,767.  %@NL@%
  3215. %@NL@%
  3216. The /Gt option applies only to compact-, large-, and huge-model programs,
  3217. since small- and medium-model programs have only one data segment. The
  3218. option is particularly useful with programs that have more than 64K of
  3219. initialized static and global data in small data items, because otherwise
  3220. you run out of memory in the default data segment and can't link the
  3221. program. The /Gt option has no effect on uninitialized global data.  %@NL@%
  3222. %@NL@%
  3223. %@NL@%
  3224. %@3@%%@CR:C6A00020042 @%%@AB@%2.4.6  Naming Modules and Segments%@AE@%%@EH@%%@NL@%
  3225. %@NL@%
  3226. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  3227. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3228. /NM %@AI@%modulename%@AE@%                    Names the module
  3229.  
  3230. /NT %@AI@%textsegment%@AE@%                   Names the code segment
  3231.  
  3232. /ND %@AI@%datasegment%@AE@%                   Names the data segment
  3233.  
  3234. "Module" is another name for an object file created by the C compiler from a
  3235. single source file. Every module has a name. The compiler uses this name in
  3236. error messages if problems are encountered during processing. The module
  3237. name is usually the same as the source-file name. You can change this name
  3238. using the /NM (name module) option. The new %@AI@%modulename%@AE@% can include any
  3239. combination of letters and digits. The space between /NM and %@AI@%modulename%@AE@% is
  3240. optional.  %@NL@%
  3241. %@NL@%
  3242. Every module has at least two segments: a code segment (sometimes called the
  3243. text segment) containing the program instructions, and a data segment
  3244. containing the program data.  %@NL@%
  3245. %@NL@%
  3246. The compiler normally creates the code and data segment names. The default
  3247. names depend on the memory model chosen for the program. For example, in
  3248. small-model programs the code segment is named %@AB@%_TEXT%@AE@% and the data segment is
  3249. named %@AB@%_DATA%@AE@%.  %@NL@%
  3250. %@NL@%
  3251. Table 2.4 summarizes the naming conventions for code and data segments.  %@NL@%
  3252. %@NL@%
  3253. %@AB@%Table 2.4  %@AB@%Segment-Naming Conventions%@AE@%%@AE@%
  3254.  
  3255. %@TH:   9   727 02 10 14 08 44 @%
  3256. Model     Code          Data    Module
  3257. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3258. Tiny      %@AB@%_TEXT%@AE@%         %@AB@%_DATA%@AE@%   ---
  3259. Small     %@AB@%_TEXT%@AE@%         %@AB@%_DATA%@AE@%   ---
  3260. Medium    %@AI@%module%@AE@%%@AB@%_TEXT%@AE@%   %@AB@%_DATA%@AE@%   %@AI@%filename%@AE@%
  3261. Compact   %@AB@%_TEXT%@AE@%         %@AB@%_DATA%@AE@%   %@AI@%filename%@AE@%
  3262. Large     %@AI@%module%@AE@%%@AB@%_TEXT%@AE@%   %@AB@%_DATA%@AE@%   %@AI@%filename%@AE@%
  3263. Huge      %@AI@%module%@AE@%%@AB@%_TEXT%@AE@%   %@AB@%_DATA%@AE@%   %@AI@%filename%@AE@%
  3264. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3265. %@TE:   9   727 02 10 14 08 44 @%
  3266.  
  3267. In memory models that contain multiple data segments (compact, large, and
  3268. huge), %@AB@%_DATA%@AE@% is the name of the default data segment. Other data segments
  3269. have unique private names. You can override the default names with the
  3270. options /NT (name text) and /ND (name data).  %@NL@%
  3271. %@NL@%
  3272. The /ND option is commonly used to create and compile modules that contain
  3273. data only. Such modules can be accessed from other parts of the program by
  3274. declaring their variables as external.  %@NL@%
  3275. %@NL@%
  3276. If you change the name of the default data segment with /ND, your program
  3277. must load the DS register with the segment selector of your named data
  3278. segment before it accesses it. You must therefore compile your program
  3279. either with the /A%@AI@%string%@AE@%form of the memory-model option and the /Au option
  3280. for the segment setup, or with the /A option for a s%@NL@%
  3281. %@NL@%
  3282. %@NL@%
  3283. %@NL@%
  3284. %@NL@%
  3285. %@CR:C6A00030001 @%%@1@%%@AB@%Chapter 3  Using the In-Line Assembler%@AE@%%@EH@%%@NL@%
  3286. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3287. %@NL@%
  3288. This chapter explains how to use the Microsoft C in-line assembler. Assembly
  3289. language serves many purposes, such as improving program speed, reducing
  3290. memory needs, and controlling hardware. The in-line assembler lets you embed
  3291. assembly-language instructions directly in your C source programs without
  3292. extra assembly and link steps. The in-line assembler is built into the
  3293. compiler─you don't need a separate assembler such as the Microsoft Macro
  3294. Assembler (MASM).  %@NL@%
  3295. %@NL@%
  3296. %@NL@%
  3297. %@2@%%@CR:C6A00030002 @%%@AB@%3.1  Advantages of In-Line Assembly%@AE@%%@EH@%%@NL@%
  3298. %@NL@%
  3299. Because the in-line assembler doesn't require separate assembly and link
  3300. steps, it is more convenient than a separate assembler. In-line assembly
  3301. code can use any C variable or function name that is in scope, so it is easy
  3302. to integrate it with your program's C code. And because the assembly code
  3303. can be mixed in-line with C statements, it can do tasks that are cumbersome
  3304. or impossible in C alone.%@CR:C6A00030003 @%  %@NL@%
  3305. %@NL@%
  3306. The uses of in-line assembly include  %@NL@%
  3307. %@NL@%
  3308. %@NL@%
  3309.   ■   Writing functions in assembly language%@NL@%
  3310. %@NL@%
  3311.   ■   Spot-optimizing speed-critical sections of code%@NL@%
  3312. %@NL@%
  3313.   ■   Calling DOS and BIOS routines with the %@AB@%INT%@AE@% instruction%@NL@%
  3314. %@NL@%
  3315.   ■   Creating TSR (terminate-and-stay-resident) code or handler routines
  3316.       that require knowledge of processor states%@NL@%
  3317. %@NL@%
  3318. %@NL@%
  3319. In-line assembly is a special-purpose tool. If you plan to transport an
  3320. application, you'll probably want to place machine-specific code in a
  3321. separate module. And because the in-line assembler doesn't support all of
  3322. MASM's macro and data directives, you may find it more convenient to use
  3323. MASM for such modules.  %@NL@%
  3324. %@NL@%
  3325. %@NL@%
  3326. %@2@%%@CR:C6A00030004 @%%@AB@%3.2  The _asm Keyword%@AE@%%@EH@%%@NL@%
  3327. %@NL@%
  3328. The %@AB@%_asm%@AE@% keyword invokes the in-line assembler and can appear wherever a C
  3329. statement is legal. It cannot appear by itself. It must be followed by an
  3330. assembly instruction, a group of instructions enclosed in braces, or, at the
  3331. very least, an empty pair of braces. The term "%@AB@%_asm%@AE@% block" here refers to
  3332. any instruction or group of instructions, whether or not in braces.  %@NL@%
  3333. %@NL@%
  3334. Below is a simple %@AB@%_asm%@AE@% block enclosed in braces. (The code prints the "beep"
  3335. character, ASCII 7.)  %@NL@%
  3336. %@NL@%
  3337. %@AS@%  _asm
  3338. %@AS@%  {
  3339. %@AS@%     mov ah, 2
  3340. %@AS@%     mov dl, 7
  3341. %@AS@%     int 21h
  3342. %@AS@%  }%@AE@%%@NL@%
  3343. %@NL@%
  3344. Alternatively, you can put %@AB@%_asm%@AE@% in front of each assembly instruction:  %@NL@%
  3345. %@NL@%
  3346. %@AS@%  _asm mov ah, 2
  3347. %@AS@%  _asm mov dl, 7
  3348. %@AS@%  _asm int 21h%@AE@%%@NL@%
  3349. %@NL@%
  3350. Since the %@AB@%_asm%@AE@% keyword is a statement separator, you can also put assembly
  3351. instructions on the same line:  %@NL@%
  3352. %@NL@%
  3353. %@AS@%  _asm mov ah, 2   _asm mov dl, 7   _asm int 21h%@AE@%%@NL@%
  3354. %@NL@%
  3355. %@AU@% Braces can prevent ambiguity and needless repetition.%@AE@%  %@NL@%
  3356. %@NL@%
  3357. All three examples generate the same code, but the first style─enclosing the
  3358. %@AB@%_asm%@AE@% block in braces─has some advantages. The braces clearly separate
  3359. assembly code from C code and avoid needless repetition of the %@AB@%_asm%@AE@% keyword.
  3360. Braces can also prevent ambiguities. If you want to put a C statement on the
  3361. same line as an %@AB@%_asm%@AE@% block, you must enclose the block in braces. Without
  3362. the braces, the compiler cannot tell where assembly code stops and C
  3363. statements begin. Finally, since the text in braces has the same format as
  3364. ordinary MASM text, you can easily cut and paste text from existing MASM
  3365. source files.  %@NL@%
  3366. %@NL@%
  3367. The braces enclosing an %@AB@%_asm%@AE@% block don't affect variable scope, as do braces
  3368. in C. You can also nest %@AB@%_asm%@AE@% blocks, but the nesting doesn't affect variable
  3369. scope.  %@NL@%
  3370. %@NL@%
  3371. %@NL@%
  3372. %@2@%%@CR:C6A00030005 @%%@AB@%3.3  Using Assembly Language in _asm Blocks%@AE@%%@EH@%%@NL@%
  3373. %@NL@%
  3374. The in-line assembler has much in common with other assemblers. For example,
  3375. it accepts any expression that is legal in MASM, and it supports all 80286
  3376. and 80287 instructions. This section describes the use of assembly-language
  3377. features in %@AB@%_asm%@AE@% blocks.  %@NL@%
  3378. %@NL@%
  3379. %@NL@%
  3380. %@4@%%@AB@%Instruction Set%@AE@%%@EH@%%@NL@%
  3381. %@NL@%
  3382. The in-line assembler supports the full instruction set of the Intel 80286
  3383. and 80287 processors. It does not recognize 80386- and 80387-specific
  3384. instructions. To use 80286 or 80287 instructions, compile with the /G2
  3385. option.  %@NL@%
  3386. %@NL@%
  3387. %@NL@%
  3388. %@4@%%@AB@%Expressions%@AE@%%@EH@%%@NL@%
  3389. %@NL@%
  3390. In-line assembly code can use any MASM expression, that is, any combination
  3391. of operands and operators that evaluates to a single value or address.  %@NL@%
  3392. %@NL@%
  3393. %@NL@%
  3394. %@4@%%@AB@%Data Directives and Operators%@AE@%%@EH@%%@NL@%
  3395. %@NL@%
  3396. Although an %@AB@%_asm%@AE@% block can reference C data types and objects, it cannot
  3397. define data objects with MASM directives or operators. Specifically, you
  3398. cannot use the definition directives %@AB@%DB%@AE@%, %@AB@%DW%@AE@%, %@AB@%DD%@AE@%, %@AB@%DQ%@AE@%, %@AB@%DT%@AE@%, and %@AB@%DF%@AE@%, or the
  3399. operators %@AB@%DUP%@AE@% or %@AB@%THIS%@AE@%. Nor are MASM structures and records available. The
  3400. in-line assembler doesn't accept the directives %@AB@%STRUC%@AE@%, %@AB@%RECORD%@AE@%, %@AB@%WIDTH%@AE@%, or
  3401. %@AB@%MASK%@AE@%.  %@NL@%
  3402. %@NL@%
  3403. %@NL@%
  3404. %@4@%%@AB@%EVEN and ALIGN Directives%@AE@%%@EH@%%@NL@%
  3405. %@NL@%
  3406. While the in-line assembler doesn't support most MASM directives, it does
  3407. support %@AB@%EVEN%@AE@% and %@AB@%ALIGN%@AE@%. These directives put %@AB@%NOP%@AE@% (no operation) instructions
  3408. in the assembly code as needed to align labels to specific boundaries. This
  3409. makes instruction-fetch operations more efficient for some processors (not
  3410. including eight-bit processors such as the Intel 8088).  %@NL@%
  3411. %@NL@%
  3412. %@NL@%
  3413. %@4@%%@AB@%Macros%@AE@%%@EH@%%@NL@%
  3414. %@NL@%
  3415. The in-line assembler is not a macro assembler. You cannot use MASM macro
  3416. directives (%@AB@%MACRO%@AE@%, %@AB@%REPT%@AE@%, %@AB@%IRC%@AE@%, %@AB@%IRP%@AE@%, and %@AB@%ENDM%@AE@%) or macro operators ( %@AB@%<>%@AE@%, %@AB@%!%@AE@%, %@AB@%&%@AE@%,
  3417. %@AB@%%%@AE@%, and %@AB@%.TYPE%@AE@%). An %@AB@%_asm%@AE@% block can use C preprocessor directives, however. See
  3418. Section 3.4, "Using C in %@AB@%_asm%@AE@% Blocks" for more information.  %@NL@%
  3419. %@NL@%
  3420. %@NL@%
  3421. %@4@%%@AB@%Segment References%@AE@%%@EH@%%@NL@%
  3422. %@NL@%
  3423. You must refer to segments by register rather than by name (the segment name
  3424. %@AB@%_TEXT%@AE@% is invalid, for instance). Segment overrides must use the register
  3425. explicitly, as in ES:[BX].  %@NL@%
  3426. %@NL@%
  3427. %@NL@%
  3428. %@4@%%@AB@%Type and Variable Sizes%@AE@%%@EH@%%@NL@%
  3429. %@NL@%
  3430. The %@AB@%LENGTH%@AE@%, %@AB@%SIZE%@AE@%, and %@AB@%TYPE%@AE@% operators have a limited meaning in in-line
  3431. assembly. They cannot be used at all with the %@AB@%DUP%@AE@% operator (because you
  3432. cannot define data with MASM directives or operators). But you can use them
  3433. to find the size of C variables or types:  %@NL@%
  3434. %@NL@%
  3435. %@NL@%
  3436.   ■   The %@AB@%LENGTH%@AE@% operator can return the number of elements in an array. It
  3437.       returns the value 1 for nonarray variables.%@NL@%
  3438. %@NL@%
  3439.   ■   The %@AB@%SIZE%@AE@% operator can return the size of a C variable. A variable's
  3440.       size is the product of its %@AB@%LENGTH%@AE@% and %@AB@%TYPE%@AE@%.%@NL@%
  3441. %@NL@%
  3442.   ■   The %@AB@%TYPE%@AE@% operator can return the size of a C type or variable. If the
  3443.       variable is an array, %@AB@%TYPE%@AE@% returns the size of a single element of the
  3444.       array.%@NL@%
  3445. %@NL@%
  3446. %@NL@%
  3447. For instance, if your program has an eight-element %@AB@%int%@AE@% array,  %@NL@%
  3448. %@NL@%
  3449. %@AS@%  int arr[8];%@AE@%%@NL@%
  3450. %@NL@%
  3451. the following C and assembly expressions yield the size of %@AS@% arr %@AE@% and its
  3452. elements:  %@NL@%
  3453. %@NL@%
  3454. %@TH:   6   425 02 12 27 37 @%
  3455. _asm        C                          Size
  3456. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3457. %@AS@%LENGTH arr%@AE@%  sizeof(ar)/sizeof(arr[0])  8
  3458. %@AS@%SIZE arr%@AE@%    sizeof (arr)               16
  3459. %@AS@%TYPE arr%@AE@%    size14(arr[0])             2
  3460. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3461. %@TE:   6   425 02 12 27 37 @%
  3462.  
  3463. %@NL@%
  3464. %@4@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  3465. %@NL@%
  3466. Instructions in an %@AB@%_asm%@AE@% block can use assembly-language comments:  %@NL@%
  3467. %@NL@%
  3468. %@AS@%  _asm mov ax, offset buff ; Load address of buff%@AE@%%@NL@%
  3469. %@NL@%
  3470. Because C macros expand into a single logical line, avoid using
  3471. assemblylanguage comments in macros (see Section 3.8, "Defining %@AB@%_asm%@AE@% Blocks
  3472. as C Macros"). An %@AB@%_asm%@AE@% block can also contain C-style comments, as noted
  3473. below.  %@NL@%
  3474. %@NL@%
  3475. %@NL@%
  3476. %@4@%%@AB@%The _emit Pseudoinstruction%@AE@%%@EH@%%@NL@%
  3477. %@NL@%
  3478. The %@AB@%_emit%@AE@% pseudoinstruction is similar to the %@AB@%DB%@AE@% directive of MASM. It
  3479. allows you to define a single immediate byte at the current location in the
  3480. current text segment. However, %@AB@%_emit%@AE@% can define only one byte at a time, and
  3481. it can only define bytes in the text segment. It uses the same syntax as the
  3482. %@AB@%INT%@AE@% instruction.  %@NL@%
  3483. %@NL@%
  3484. One use for %@AB@%_emit%@AE@% is to define 80386-specific instructions, which the
  3485. in-line assembler does not support. The following fragment, for instance,
  3486. defines the 80386 %@AB@%CWDE%@AE@% instruction:  %@NL@%
  3487. %@NL@%
  3488. %@AS@%  /* Assumes 16-bit mode */
  3489. %@AS@%  #define cwde _asm _emit 0x66 _asm _emit 0x98
  3490. %@AS@%   .
  3491. %@AS@%   .
  3492. %@AS@%   .
  3493. %@AS@%  _asm {
  3494. %@AS@%       cwde
  3495. %@AS@%       }%@AE@%%@NL@%
  3496. %@NL@%
  3497. %@NL@%
  3498. %@4@%%@AB@%Debugging and Listings%@AE@%%@EH@%%@NL@%
  3499. %@NL@%
  3500. %@AU@% In-line assembly code can be debugged with CodeView.%@AE@%  %@NL@%
  3501. %@NL@%
  3502. Programs containing in-line assembly code can be debugged with the CodeView
  3503. debugger, assuming you compile with the /Zi option.  %@NL@%
  3504. %@NL@%
  3505. Within CodeView, you can set breakpoints on both C and assembly-language
  3506. lines. If you enable mixed assembly and C mode, you can display both the
  3507. source and disassembled form of the assembly code.  %@NL@%
  3508. %@NL@%
  3509. Note that putting multiple assembly instructions or C statements on one line
  3510. can hamper debugging with CodeView. In source mode, the CodeView debugger
  3511. lets you set breakpoints on a single line but not on individual statements
  3512. on the same line. The same principle applies to an %@AB@%_asm%@AE@% block defined as a C
  3513. macro, which expands to a single logical line.  %@NL@%
  3514. %@NL@%
  3515. If you create a mixed source and assembly listing with the /Fc compiler
  3516. option, the listing contains both the source and assembly forms of each
  3517. assemblylanguage line. Macros are not expanded in listings, but they are
  3518. expanded during compilation.  %@NL@%
  3519. %@NL@%
  3520. See Chapter 9, "Debugging C Programs with CodeView," for more information.  %@NL@%
  3521. %@NL@%
  3522. %@NL@%
  3523. %@2@%%@CR:C6A00030006 @%%@AB@%3.4  Using C in _asm Blocks%@AE@%%@EH@%%@NL@%
  3524. %@NL@%
  3525. Because in-line assembly instructions can be mixed with C statements, they
  3526. can refer to C variables by name and use many other elements of C. An %@AB@%_asm%@AE@%
  3527. block can use the following C language elements:  %@NL@%
  3528. %@NL@%
  3529. %@NL@%
  3530.   ■   Symbols, including labels and variable and function names%@NL@%
  3531. %@NL@%
  3532.   ■   Constants, including symbolic constants and %@AB@%enum%@AE@% members%@NL@%
  3533. %@NL@%
  3534.   ■   Macros and preprocessor directives%@NL@%
  3535. %@NL@%
  3536.   ■   Comments (both %@AS@% /* */ %@AE@% and %@AS@% // %@AE@%)%@NL@%
  3537. %@NL@%
  3538.   ■   Type names (wherever a MASM type would be legal)%@NL@%
  3539. %@NL@%
  3540.   ■   %@AB@%typedef%@AE@% names, generally used with operators such as %@AB@%PTR%@AE@% and %@AB@%TYPE%@AE@% or
  3541.       to specify structure or union members%@NL@%
  3542. %@NL@%
  3543. %@NL@%
  3544. Within an %@AB@%_asm%@AE@% block, you can specify integer constants with either C
  3545. notation or assembler radix notation (0x100 and 100h are equivalent, for
  3546. instance). This allows you to define (using %@AB@%#define%@AE@%) a constant in C, and
  3547. use it in both C and assembly portions of the program. You can also specify
  3548. constants in octal by preceding them with a 0. For example, 0777 specifies
  3549. an octal constant.  %@NL@%
  3550. %@NL@%
  3551. %@NL@%
  3552. %@3@%%@CR:C6A00030007 @%%@AB@%3.4.1  Using Operators%@AE@%%@EH@%%@NL@%
  3553. %@NL@%
  3554. An %@AB@%_asm%@AE@% block cannot use C-specific operators, such as the %@AB@%%@AE@% operator.
  3555. However, operators shared by C and MASM, such as the %@AB@%*%@AE@% operator, are
  3556. interpreted as assembly-language operators. For instance, outside an %@AB@%_asm%@AE@%
  3557. block, square brackets (%@AB@% [] %@AE@%) are interpreted as enclosing array subscripts,
  3558. which C automatically scales to the size of an element in the array. Inside
  3559. an %@AB@%_asm%@AE@% block, they are seen as the MASM index operator, which yields an
  3560. unscaled byte offset from any data object or label (not just an array). The
  3561. following code illustrates the difference:  %@NL@%
  3562. %@NL@%
  3563. %@AS@%  int array[10];
  3564. %@AS@%  
  3565. %@AS@%  _asm mov array[6], bx ;  Store BX at array+6 (not scaled)
  3566. %@AS@%  
  3567. %@AS@%  array[6] = 0;         /* Store 0 at array+12 (scaled) */%@AE@%%@NL@%
  3568. %@NL@%
  3569. The first reference to %@AS@% array %@AE@% is not scaled, but the second is. Note that
  3570. you can use the %@AB@%TYPE%@AE@% operator to achieve scaling based on a constant. For
  3571. instance, the following statements are equivalent:  %@NL@%
  3572. %@NL@%
  3573. %@AS@%  _asm mov array[6 * TYPE int], 0 ; Store 0 at array + 12
  3574. %@AS@%  
  3575. %@AS@%  array[6] = 0;                   /* Store 0 at array + 12 */%@AE@%%@NL@%
  3576. %@NL@%
  3577. %@NL@%
  3578. %@3@%%@CR:C6A00030008 @%%@AB@%3.4.2  Using C Symbols%@AE@%%@EH@%%@NL@%
  3579. %@NL@%
  3580. An %@AB@%_asm%@AE@% block can refer to any C symbol in scope where the block appears. (C
  3581. symbols are variable names, function names, and labels─in other words, names
  3582. that aren't symbolic constants or %@AB@%enum%@AE@% members.)  %@NL@%
  3583. %@NL@%
  3584. A few restrictions apply to the use of C symbols:  %@NL@%
  3585. %@NL@%
  3586. %@NL@%
  3587.   ■   Each assembly-language statement can contain only one C symbol.
  3588.       Multiple symbols can appear in the same assembly instruction only with
  3589.       %@AB@%LENGTH, TYPE%@AE@%, and %@AB@%SIZE%@AE@% expressions.%@NL@%
  3590. %@NL@%
  3591.   ■   Functions referenced in an %@AB@%_asm%@AE@% block must be declared (prototyped)
  3592.       earlier in the program. Otherwise, the compiler cannot distinguish
  3593.       between function names and labels in the %@AB@%_asm%@AE@% block.%@NL@%
  3594. %@NL@%
  3595.   ■   An %@AB@%_asm%@AE@% block cannot use any C symbols with the same spelling as MASM
  3596.       reserved words (regardless of case). MASM reserved words include
  3597.       instruction names such as %@AB@%PUSH%@AE@% and register names such as SI.%@NL@%
  3598. %@NL@%
  3599.   ■   Structure and union tags are not recognized in %@AB@%_asm%@AE@% blocks.%@NL@%
  3600. %@NL@%
  3601. %@NL@%
  3602. %@NL@%
  3603. %@3@%%@CR:C6A00030009 @%%@AB@%3.4.3  Accessing C Data%@AE@%%@EH@%%@NL@%
  3604. %@NL@%
  3605. A great convenience of in-line assembly is the ability to refer to C
  3606. variables by name. An %@AB@%_asm%@AE@% block can refer to any symbols─including variable
  3607. names─that are in scope where the block appears. For instance, if the C
  3608. variable %@AS@% var %@AE@% is in scope, the instruction  %@NL@%
  3609. %@NL@%
  3610. %@AS@%  _asm mov ax, var%@AE@%%@NL@%
  3611. %@NL@%
  3612. stores the value of %@AS@% var %@AE@% in AX.  %@NL@%
  3613. %@NL@%
  3614. If a structure or union member has a unique name, an %@AB@%_asm%@AE@% block can refer to
  3615. it using only the member name, without specifying the C variable or %@AB@%typedef%@AE@%
  3616. name before the period (%@AB@%.%@AE@%) operator. If the member name is not unique,
  3617. however, you must place a variable or %@AB@%typedef%@AE@% name immediately before the
  3618. period (%@AB@%.%@AE@%) operator. For instance, the following structure types share %@AS@%
  3619. %@AS@%same_name %@AE@% as their member name: %@AS@%  %@AE@%%@NL@%
  3620. %@NL@%
  3621. %@AS@%  struct first_type
  3622. %@AS@%  {
  3623. %@AS@%     char *weasel;
  3624. %@AS@%     int same_name;
  3625. %@AS@%  };
  3626. %@AS@%  
  3627. %@AS@%  struct second_type
  3628. %@AS@%  {
  3629. %@AS@%     int wonton;
  3630. %@AS@%     long same_name;
  3631. %@AS@%  };%@AE@%%@NL@%
  3632. %@NL@%
  3633. If you declare variables with the types  %@NL@%
  3634. %@NL@%
  3635. %@AS@%  struct first_type hal;
  3636. %@AS@%  struct second_type oat;%@AE@%%@NL@%
  3637. %@NL@%
  3638. all references to the member %@AS@% same_name %@AE@% must use the variable name, because
  3639. %@AS@% same_name %@AE@% is not unique. But the member %@AS@% weasel %@AE@% has a unique name, so you
  3640. can refer to it using only its member name:  %@NL@%
  3641. %@NL@%
  3642. %@AS@%  _asm
  3643. %@AS@%  {
  3644. %@AS@%     mov bx, OFFSET hal
  3645. %@AS@%     mov cx, [bx]hal.same_name ; Must use 'hal'
  3646. %@AS@%     mov si, [bx].weasel       ; Can omit 'hal'
  3647. %@AS@%  }%@AE@%%@NL@%
  3648. %@NL@%
  3649. Note that omitting the variable name is merely a coding convenience. The
  3650. same assembly instructions are generated whether or not it is present.  %@NL@%
  3651. %@NL@%
  3652. %@NL@%
  3653. %@3@%%@CR:C6A00030010 @%%@AB@%3.4.4  Writing Functions%@AE@%%@EH@%%@NL@%
  3654. %@NL@%
  3655. If you write a function with in-line assembly code, it's a simple matter to
  3656. pass arguments to the function and return a value from it. The following
  3657. examples compare a function first written for a separate assembler and then
  3658. rewritten for the in-line assembler. The function, called %@AS@% power2%@AE@%, receives
  3659. two parameters, multiplying the first parameter by 2 to the power of the
  3660. second parameter. Written for a separate assembler, the function might look
  3661. like this:  %@NL@%
  3662. %@NL@%
  3663. %@AS@%  ; POWER.ASM
  3664. %@AS@%  ; Compute the power of an integer
  3665. %@AS@%  ;
  3666. %@AS@%         PUBLIC _power2
  3667. %@AS@%  _TEXT SEGMENT WORD PUBLIC 'CODE'
  3668. %@AS@%  _power2 PROC
  3669. %@AS@%  
  3670. %@AS@%          push bp         ; Save BP
  3671. %@AS@%          mov bp, sp      ; Move SP into BP so we can refer
  3672. %@AS@%                          ;   to arguments on the stack
  3673. %@AS@%          mov ax, [bp+4]  ; Get first argument
  3674. %@AS@%          mov cx, [bp+6]  ; Get second argument
  3675. %@AS@%          shl ax, cl      ; AX = AX * ( 2 ^ CL )
  3676. %@AS@%          pop bp          ; Restore BP
  3677. %@AS@%          ret             ; Return with sum in AX
  3678. %@AS@%  
  3679. %@AS@%  _power2 ENDP
  3680. %@AS@%  _TEXT   ENDS
  3681. %@AS@%          END%@AE@%%@NL@%
  3682. %@NL@%
  3683. %@AU@% Function arguments are usually passed on the stack.%@AE@%  %@NL@%
  3684. %@NL@%
  3685. Since it's written for a separate assembler, the function requires a
  3686. separate source file and assembly and link steps. C function arguments
  3687. usually are passed on the stack, so this version of the %@AS@% power2 %@AE@% function
  3688. accesses its arguments by their positions on the stack. (Note that the %@AB@%MODEL%@AE@%
  3689. directive, available in MASM and some other assemblers, also allows you to
  3690. access stack arguments and local stack variables by name.)  %@NL@%
  3691. %@NL@%
  3692. The POWER2.C program below writes the %@AS@% power2 %@AE@% function with in-line
  3693. assembly code:  %@NL@%
  3694. %@NL@%
  3695. %@AS@%  /* POWER2.C */
  3696. %@AS@%  #include <stdio.h>
  3697. %@AS@%  
  3698. %@AS@%  int power2( int num, int power );
  3699. %@AS@%  
  3700. %@AS@%  void main( void )
  3701. %@AS@%  {
  3702. %@AS@%     printf( "3 times 2 to the power of 5 is %d\n", \
  3703. %@AS@%             power2( 3, 5) );
  3704. %@AS@%  }
  3705. %@AS@%  
  3706. %@AS@%  int power2( int num, int power )
  3707. %@AS@%  {
  3708. %@AS@%     _asm
  3709. %@AS@%     {
  3710. %@AS@%        mov ax, num    ; Get first argument
  3711. %@AS@%        mov cx, power  ; Get second argument
  3712. %@AS@%        shl ax, cl     ; AX = AX * ( 2 to the power of CL )
  3713. %@AS@%     }
  3714. %@AS@%     /* Return with result in AX */
  3715. %@AS@%  }%@AE@%%@NL@%
  3716. %@NL@%
  3717. The in-line version of the %@AS@% power2 %@AE@% function refers to its arguments by name
  3718. and appears in the same source file as the rest of the program. This version
  3719. also requires fewer assembly instructions. Since C automatically preserves
  3720. BP, the %@AB@%_asm%@AE@% block doesn't need to do so. It can also dispense with the %@AB@%RET%@AE@%
  3721. instruction, since the C part of the function performs the return.  %@NL@%
  3722. %@NL@%
  3723. Because the in-line version of %@AS@% power2 %@AE@% doesn't execute a C %@AB@%return%@AE@%
  3724. statement, it causes a harmless warning if you compile at warning levels 2
  3725. or higher:  %@NL@%
  3726. %@NL@%
  3727. %@AS@%  warning C4035: 'power2' : no return value%@AE@%%@NL@%
  3728. %@NL@%
  3729. The function does return a value, but the compiler cannot tell that in the
  3730. absence of a %@AB@%return%@AE@% statement. Simply ignore the warning in this context.  %@NL@%
  3731. %@NL@%
  3732. %@NL@%
  3733. %@2@%%@CR:C6A00030011 @%%@AB@%3.5  Using and Preserving Registers%@AE@%%@EH@%%@NL@%
  3734. %@NL@%
  3735. In general, you should not assume that a register will have a given value
  3736. when an %@AB@%_asm%@AE@% block begins. An %@AB@%_asm%@AE@% block inherits whatever register values
  3737. happen to result from the normal flow of control.  %@NL@%
  3738. %@NL@%
  3739. If you use the %@AB@%_fastcall%@AE@% calling convention, the compiler passes function
  3740. arguments in registers instead of the stack. This can create problems in
  3741. functions with %@AB@%_asm%@AE@% blocks, since a function has no way to tell which
  3742. parameter is in which register. If the function happens to receive a
  3743. parameter in AX and immediately stores something else in AX, the parameter
  3744. is lost. In addition, you must preserve the CX and ES registers in any
  3745. function declared with %@AB@%_fastcall%@AE@%.  %@NL@%
  3746. %@NL@%
  3747. %@AU@% Don't use the _fastcall calling convention for functions with _asm blocks.%@AE@%
  3748. %@NL@%
  3749. %@NL@%
  3750. To avoid such register conflicts, don't use the %@AB@%_fastcall%@AE@% convention for
  3751. functions that contain an %@AB@%_asm%@AE@% block. If you specify the %@AB@%_fastcall%@AE@%
  3752. convention globally with the /Gr compiler option, declare every function
  3753. containing an %@AB@%_asm%@AE@% block with %@AB@%_cdecl%@AE@%. (The %@AB@%_cdecl%@AE@% attribute tells the
  3754. compiler to use the normal C calling convention for that function.) If you
  3755. are not compiling with /Gr, avoid declaring the function with the %@AB@%_fastcall%@AE@%
  3756. attribute.  %@NL@%
  3757. %@NL@%
  3758. As you may have noticed in the POWER2.C example in Section 3.4.4, the %@AS@%
  3759. %@AS@%power2 %@AE@% function doesn't preserve the value in the AX register. When you
  3760. write a function in assembly language, you don't need to preserve the AX,
  3761. BX, CX, DX, ES, and flags registers. However, you should preserve any other
  3762. registers you use (DI, SI, DS, SS, SP, and BP).  %@NL@%
  3763. %@NL@%
  3764. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3765. %@AU@%WARNING%@AE@%%@NL@%
  3766. %@NL@%
  3767. If your in-line assembly code changes the direction flag using the STD or
  3768. CLD instructions, you must restore the flag to its original value.%@NL@%
  3769. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3770. %@NL@%
  3771. %@AU@% Functions return values in the AX and DX registers.%@AE@%  %@NL@%
  3772. %@NL@%
  3773. The POWER2.C example in Section 3.4.4 also shows that functions return
  3774. values in registers. This is true whether the function is written in
  3775. assembly language or in C.  %@NL@%
  3776. %@NL@%
  3777. If the return value is short (a %@AB@%char%@AE@%, %@AB@%int%@AE@%, or %@AB@%near%@AE@% pointer), it is stored in
  3778. AX. The POWER2.C example returned a value by terminating with the desired
  3779. value in AX.  %@NL@%
  3780. %@NL@%
  3781. If the return value is long, store the high word in DX and the low word in
  3782. AX. To return a longer value (such as a floating-point value), store the
  3783. value in memory and return a pointer to the value (in AX if %@AB@%near%@AE@% or in DX:AX
  3784. if %@AB@%far%@AE@%).  %@NL@%
  3785. %@NL@%
  3786. Assembly instructions that appear in-line with C statements are free to
  3787. alter the AX, BX, CX, and DX registers. C doesn't expect these registers to
  3788. be maintained between statements, so you don't need to preserve them. The
  3789. same is true of the SI and DI registers, with some exceptions (see Section
  3790. 3.9, "Optimizing"). You should preserve the SP and BP registers unless you
  3791. have some reason to change them─to switch stacks, for instance.  %@NL@%
  3792. %@NL@%
  3793. %@NL@%
  3794. %@2@%%@CR:C6A00030012 @%%@AB@%3.6  Jumping to Labels%@AE@%%@EH@%%@NL@%
  3795. %@NL@%
  3796. Like an ordinary C label, a label in an %@AB@%_asm%@AE@% block has scope throughout the
  3797. function in which it is defined (not only in the block). Both assembly
  3798. instructions and C %@AB@%goto%@AE@% statements can jump to labels inside or outside the
  3799. %@AB@%_asm%@AE@% block.  %@NL@%
  3800. %@NL@%
  3801. %@AU@% Labels in _asm blocks have function scope and are not case sensitive.%@AE@%  %@NL@%
  3802. %@NL@%
  3803. Unlike C labels, labels defined in %@AB@%_asm%@AE@% blocks are not case sensitive, even
  3804. when used in C statements. C labels are not case sensitive in an %@AB@%_asm%@AE@% block,
  3805. either. (Outside an %@AB@%_asm%@AE@% block, a C label is case sensitive as usual.) The
  3806. following do-nothing code shows all the permutations:  %@NL@%
  3807. %@NL@%
  3808. %@AS@%  void func( void )
  3809. %@AS@%  {
  3810. %@AS@%     goto C_Dest;  /* legal */
  3811. %@AS@%     goto c_dest;  /* error */
  3812. %@AS@%  
  3813. %@AS@%     goto A_Dest;  /* legal */
  3814. %@AS@%     goto a_dest;  /* legal */
  3815. %@AS@%  
  3816. %@AS@%     _asm
  3817. %@AS@%     {
  3818. %@AS@%        jmp C_Dest ; legal
  3819. %@AS@%        jmp c_dest ; legal
  3820. %@AS@%  
  3821. %@AS@%        jmp A_Dest ; legal
  3822. %@AS@%        jmp a_dest ; legal
  3823. %@AS@%  
  3824. %@AS@%        a_dest:    ; _asm label
  3825. %@AS@%     }
  3826. %@AS@%  
  3827. %@AS@%     C_Dest:       /* C label */ 
  3828. %@AS@%     return;
  3829. %@AS@%  }%@AE@%%@NL@%
  3830. %@NL@%
  3831. Don't use C library function names as labels in %@AB@%_asm%@AE@% blocks. For instance,
  3832. you might be tempted to use %@AS@% exit %@AE@% as a label,  %@NL@%
  3833. %@NL@%
  3834. %@AS@%  jne exit
  3835. %@AS@%     .
  3836. %@AS@%     .
  3837. %@AS@%     .
  3838. %@AS@%  exit:
  3839. %@AS@%     ; More _asm code follows%@AE@%%@NL@%
  3840. %@NL@%
  3841. forgetting that %@AB@%exit%@AE@% is the name of a C library function. The code doesn't
  3842. cause a compiler error, but it might cause a jump to the %@AB@%exit%@AE@% function
  3843. instead of the desired location.  %@NL@%
  3844. %@NL@%
  3845. As in MASM programs, the dollar symbol (%@AB@%$%@AE@%) serves as the current location
  3846. counter─a label for the instruction currently being assembled. In %@AB@%_asm%@AE@%
  3847. blocks, its main use is to make long conditional jumps:  %@NL@%
  3848. %@NL@%
  3849. %@AS@%  jne $+5 ; next instruction is 5 bytes long
  3850. %@AS@%  jmp farlabel
  3851. %@AS@%  ; $+5
  3852. %@AS@%     .
  3853. %@AS@%     .
  3854. %@AS@%     .
  3855. %@AS@%  farlabel:%@AE@%%@NL@%
  3856. %@NL@%
  3857. %@NL@%
  3858. %@2@%%@CR:C6A00030013 @%%@AB@%3.7  Calling C Functions%@AE@%%@EH@%%@NL@%
  3859. %@NL@%
  3860. An %@AB@%_asm%@AE@% block can call C functions, including C library routines. The
  3861. following example calls the %@AB@%printf%@AE@% library routine:  %@NL@%
  3862. %@NL@%
  3863. %@AS@%  #include <stdio.h>
  3864. %@AS@%  
  3865. %@AS@%  char format[] = "%s %s\n";
  3866. %@AS@%  char hello[] = "Hello";
  3867. %@AS@%  char world[] = "world";
  3868. %@AS@%  
  3869. %@AS@%  void main( void )
  3870. %@AS@%  {
  3871. %@AS@%     _asm
  3872. %@AS@%     {
  3873. %@AS@%        mov  ax, offset world
  3874. %@AS@%        push ax
  3875. %@AS@%        mov  ax, offset hello
  3876. %@AS@%        push ax
  3877. %@AS@%        mov  ax, offset format
  3878. %@AS@%        push ax
  3879. %@AS@%        call printf
  3880. %@AS@%     }
  3881. %@AS@%  }%@AE@%%@NL@%
  3882. %@NL@%
  3883. Since function arguments are passed on the stack, you simply push the needed
  3884. arguments─string pointers, in the example above─before calling the function.
  3885. The arguments are pushed in reverse order, so they come off the stack in the
  3886. desired order. To emulate the C statement  %@NL@%
  3887. %@NL@%
  3888. %@AS@%  printf( format, hello, world );%@AE@%%@NL@%
  3889. %@NL@%
  3890. the example pushes pointers to %@AS@% world%@AE@%, %@AS@% hello%@AE@%, and %@AS@% format%@AE@%, in that order,
  3891. then calls %@AB@%printf%@AE@%.  %@NL@%
  3892. %@NL@%
  3893. %@NL@%
  3894. %@2@%%@CR:C6A00030014 @%%@AB@%3.8  Defining _asm Blocks as C Macros%@AE@%%@EH@%%@NL@%
  3895. %@NL@%
  3896. C macros offer a convenient way to insert assembly code into C code, but
  3897. they demand extra care because a macro expands into a single logical line.
  3898. To create trouble-free macros, follow these rules:  %@NL@%
  3899. %@NL@%
  3900. %@NL@%
  3901.   ■   Enclose the %@AB@%_asm%@AE@% block in braces.%@NL@%
  3902. %@NL@%
  3903.   ■   Put the %@AB@%_asm%@AE@% keyword in front of each assembly instruction.%@NL@%
  3904. %@NL@%
  3905.   ■   Use old-style C comments (%@AS@% /* comment */ %@AE@%) instead of assembly-style
  3906.       comments (%@AS@% ; comment %@AE@%) or single-line C comments (%@AS@% // comment %@AE@%).%@NL@%
  3907. %@NL@%
  3908. %@NL@%
  3909. To illustrate, the following example defines a simple macro:  %@NL@%
  3910. %@NL@%
  3911. %@AS@%  #define BEEP _asm \
  3912. %@AS@%  /* Beep sound */       \
  3913. %@AS@%  {                       \
  3914. %@AS@%     _asm mov ah, 2       \
  3915. %@AS@%     _asm mov dl, 7       \
  3916. %@AS@%     _asm int 21h         \
  3917. %@AS@%  }%@AE@%%@NL@%
  3918. %@NL@%
  3919. At first glance, the last three %@AB@%_asm%@AE@% keywords seem superfluous. They are
  3920. needed, however, because the macro expands into a single line:  %@NL@%
  3921. %@NL@%
  3922. %@AS@%  _asm /* Beep sound */ { _asm mov ah, 2  _asm mov dl, 7 _asm int 21h }%@AE@%%@NL@%
  3923. %@NL@%
  3924. The third and fourth %@AB@%_asm%@AE@% keywords are needed as statement separators. The
  3925. only statement separators recognized in %@AB@%_asm%@AE@% blocks are the newline
  3926. character and %@AB@%_asm%@AE@% keyword. And since a block defined as a macro is one
  3927. logical line, you must separate each instruction with %@AB@%_asm%@AE@%.  %@NL@%
  3928. %@NL@%
  3929. The braces are essential as well. If you omit them, the compiler can be
  3930. confused by C statements on the same line to the right of the macro
  3931. invocation. Without the closing brace, the compiler cannot tell where
  3932. assembly code stops, and it sees C statements after the %@AB@%_asm%@AE@% block as
  3933. assembly instructions.  %@NL@%
  3934. %@NL@%
  3935. %@AU@% Use C comments in _asm blocks written as macros.%@AE@%  %@NL@%
  3936. %@NL@%
  3937. Assembly-style comments that start with a semicolon (;) continue to the end
  3938. of the line. This causes problems in macros because the compiler ignores
  3939. everything after the comment, all the way to the end of the logical line.
  3940. The same is true of single-line C comments (%@AS@% // comment %@AE@%). To prevent
  3941. errors, use old-style C comments (%@AS@% /* comment */ %@AE@%) in %@AB@%_asm%@AE@% blocks defined as
  3942. macros.  %@NL@%
  3943. %@NL@%
  3944. %@AU@% An _asm block written as a C macro can take arguments but cannot return a
  3945. %@AU@%value.%@AE@%  %@NL@%
  3946. %@NL@%
  3947. An %@AB@%_asm%@AE@% block written as a C macro can take arguments. Unlike an ordinary C
  3948. macro, however, an %@AB@%_asm%@AE@% macro cannot return a value. So you cannot use such
  3949. macros in C expressions.  %@NL@%
  3950. %@NL@%
  3951. Be careful not to invoke macros of this type indiscriminately. For instance,
  3952. invoking an assembly-language macro in a function declared with the
  3953. %@AB@%_fastcall%@AE@% con-vention may cause unexpected results. (See Section 3.5, "Using
  3954. and Preserving Registers.")  %@NL@%
  3955. %@NL@%
  3956. %@AU@% You can convert MASM macros to C macros.%@AE@%  %@NL@%
  3957. %@NL@%
  3958. Note that some MASM-style macros can be written as C macros. Below is a MASM
  3959. macro that sets the video page to the value specified in the %@AS@% page %@AE@%
  3960. argument:  %@NL@%
  3961. %@NL@%
  3962. %@AS@%  setpage   MACRO page
  3963. %@AS@%            mov ah, 5
  3964. %@AS@%            mov al, page
  3965. %@AS@%            int 10h
  3966. %@AS@%            ENDM%@AE@%%@NL@%
  3967. %@NL@%
  3968. The following code defines %@AS@% setpage %@AE@% as a C macro:  %@NL@%
  3969. %@NL@%
  3970. %@AS@%  #define setpage( page ) _asm  \
  3971. %@AS@%     {                                \
  3972. %@AS@%        _asm mov ah, 5                \
  3973. %@AS@%        _asm mov al, page             \
  3974. %@AS@%        _asm int 10h                  \
  3975. %@AS@%  }%@AE@%%@NL@%
  3976. %@NL@%
  3977. Both macros do the same job.  %@NL@%
  3978. %@NL@%
  3979. %@NL@%
  3980. %@2@%%@CR:C6A00030015 @%%@AB@%3.9  Optimizing%@AE@%%@EH@%%@NL@%
  3981. %@NL@%
  3982. The presence of an %@AB@%_asm%@AE@% block in a function affects optimization in a few
  3983. different ways. First, as you might expect, the compiler doesn't try to
  3984. optimize the %@AB@%_asm%@AE@% block itself. What you write in assembly language is
  3985. exactly what you get.  %@NL@%
  3986. %@NL@%
  3987. Second, the presence of an %@AB@%_asm%@AE@% block affects register variable storage.
  3988. Under normal circumstances (unless you suppress optimization with the /Od
  3989. option) the compiler automatically stores variables in registers. This is
  3990. not done, however, in any function that contains an %@AB@%_asm%@AE@% block. To get
  3991. register variable storage in such a function, you must request it with the
  3992. %@AB@%register%@AE@% keyword.  %@NL@%
  3993. %@NL@%
  3994. Since the compiler stores register variables in the SI and DI registers,
  3995. these registers represent variables in functions that request register
  3996. storage. The first eligible variable is stored in SI and the second in DI.
  3997. Preserve SI and DI in such functions unless you want to change the register
  3998. variables.  %@NL@%
  3999. %@NL@%
  4000. Keep in mind that the name of a variable declared with %@AB@%register%@AE@% translates
  4001. directly into a register reference (assuming a register is available for
  4002. such use). For instance, if you declare  %@NL@%
  4003. %@NL@%
  4004. %@AS@%  register int sample;%@AE@%%@NL@%
  4005. %@NL@%
  4006. and the variable %@AS@% sample %@AE@% happens to be stored in SI, then the %@AB@%_asm%@AE@%
  4007. instruction  %@NL@%
  4008. %@NL@%
  4009. %@AS@%  _asm mov ax, sample%@AE@%%@NL@%
  4010. %@NL@%
  4011. is equivalent to  %@NL@%
  4012. %@NL@%
  4013. %@AS@%  _asm mov ax, si%@AE@%%@NL@%
  4014. %@NL@%
  4015. If you declare a variable with %@AB@%register%@AE@% and the compiler cannot store the
  4016. variable in a register, the compiler issues a warning to that effect at
  4017. compile time. The solution is to remove the %@AB@%register%@AE@% declaration from that
  4018. variable.  %@NL@%
  4019. %@NL@%
  4020. Register variables form a slight exception to the general rule that an
  4021. assembly-language statement can contain no more than one C symbol. If one of
  4022. the symbols is a register variable, for example,  %@NL@%
  4023. %@NL@%
  4024. %@AS@%  register int v1;
  4025. %@AS@%  int v2;%@AE@%%@NL@%
  4026. %@NL@%
  4027. then an instruction can use two C symbols, as in  %@NL@%
  4028. %@NL@%
  4029. %@AS@%  mov v1, v2%@AE@%%@NL@%
  4030. %@NL@%
  4031. Finally, the presence of in-line assembly code inhibits the following
  4032. optimizations for the entire function in which the code appears:  %@NL@%
  4033. %@NL@%
  4034. %@NL@%
  4035.   ■   Loop ( /Ol )%@NL@%
  4036. %@NL@%
  4037.   ■   Global register allocation ( /Oe )%@NL@%
  4038. %@NL@%
  4039.   ■   Global optimizations and common subexpressions ( /Og )%@NL@%
  4040. %@NL@%
  4041. %@NL@%
  4042. These optimizations are suppressed no matter which compiler options you use.
  4043. %@NL@%
  4044. %@NL@%
  4045. %@NL@%
  4046. %@NL@%
  4047. %@NL@%
  4048. %@NL@%
  4049. %@NL@%
  4050. %@CR:C6A00040001 @%%@1@%%@AB@%Chapter 4  Controlling Floating-Point Math Operations%@AE@%%@EH@%%@NL@%
  4051. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4052. %@NL@%
  4053. This chapter describes how to control the way your Microsoft C programs
  4054. perform floating-point math operations. It describes the math packages that
  4055. you can include in C libraries when you run the SETUP program, then
  4056. discusses  the options you can specify in the Programmer's WorkBench (PWB)
  4057. or on the CL command line to choose the appropriate library for linking and
  4058. controlling floating-point instructions.%@CR:C6A00040002 @%  %@NL@%
  4059. %@NL@%
  4060. This chapter also explains how to override floating-point options by
  4061. changing libraries at link time, and how to control use of the Intel math
  4062. coprocessor (80%@AI@%x%@AE@%87) using the NO87 environment variable.%@CR:C6A00040003 @%%@CR:C6A00040004 @%%@CR:C6A00040005 @%%@CR:C6A00040006 @%  %@NL@%
  4063. %@NL@%
  4064. %@NL@%
  4065. %@2@%%@CR:C6A00040007 @%%@AB@%4.1  Declaring Floating-Point Types%@AE@%%@EH@%%@NL@%
  4066. %@NL@%
  4067. Microsoft C supports three floating-point types that conform to the
  4068. Institute of Electrical and Electronics Engineers (IEEE) standard 754
  4069. format:%@CR:C6A00040008 @%  %@NL@%
  4070. %@NL@%
  4071. %@NL@%
  4072.   1.  Type %@AB@%float%@AE@%, a 32-bit floating-point quantity%@NL@%
  4073. %@NL@%
  4074.   2.  Type %@AB@%double%@AE@%, a 64-bit floating-point quantity%@NL@%
  4075. %@NL@%
  4076.   3.  Type %@AB@%long double%@AE@%, an 80-bit floating-point quantity%@NL@%
  4077. %@NL@%
  4078. %@NL@%
  4079. You can declare variables as any of these types. You can also declare
  4080. functions that return any of these types.  %@NL@%
  4081. %@NL@%
  4082. %@NL@%
  4083. %@3@%%@CR:C6A00040009 @%%@AB@%4.1.1  Declaring Variables as Floating-Point Types%@CR:C6A00040010 @%%@AE@%%@EH@%%@NL@%
  4084. %@NL@%
  4085. You can declare variables as %@AB@%float%@AE@%, %@AB@%double%@AE@%, or %@AB@%long double%@AE@%, depending on the
  4086. needs of your application. The principal differences between the three types
  4087. are the significance they can represent, the storage they require, and their
  4088. range. Table 4.1 shows the relationship between significance and storage
  4089. requirements.%@CR:C6A00040011 @%%@CR:C6A00040012 @%%@CR:C6A00040013 @%%@CR:C6A00040014 @%%@CR:C6A00040015 @%%@CR:C6A00040016 @%%@CR:C6A00040017 @%%@CR:C6A00040018 @%%@CR:C6A00040019 @%%@CR:C6A00040020 @%  %@NL@%
  4090. %@NL@%
  4091. %@AB@%Table 4.1  %@AB@%Floating-Point Types%@AE@%%@AE@%
  4092.  
  4093. %@TH:   6   416 02 14 20 42 @%
  4094. Type          Significant Digits  Number of Bytes
  4095. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4096. %@AB@%float%@AE@%         6-7                 4
  4097. %@AB@%double%@AE@%        15-16               8
  4098. %@AB@%long double%@AE@%   19                  10
  4099. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4100. %@TE:   6   416 02 14 20 42 @%
  4101.  
  4102. Floating-point variables are represented by a mantissa, which contains the
  4103. value of the number, and an exponent, which contains the order of magnitude
  4104. of the number.%@CR:C6A00040021 @%%@CR:C6A00040022 @%  %@NL@%
  4105. %@NL@%
  4106. Table 4.2 shows the number of bits allocated to the mantissa and the
  4107. exponent for each floating-point type. The most-significant bit of any
  4108. %@AB@%float%@AE@%, %@AB@%double%@AE@%, or %@AB@%long double %@AE@%is always the sign bit. If it is 1, the number
  4109. is considered negative; otherwise, it is considered a positive number.%@CR:C6A00040023 @%  %@NL@%
  4110. %@NL@%
  4111. %@AB@%Table 4.2  %@AB@%Lengths of Exponents and Mantissas%@AE@%%@AE@%
  4112.  
  4113. %@TH:   6   421 02 14 17 45 @%
  4114. Type          Exponent Length  Mantissa Length
  4115. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4116. %@AB@%float%@AE@%         8 bits           23 bits
  4117. %@AB@%double%@AE@%        11 bits          52 bits
  4118. %@AB@%long double%@AE@%   15 bits          64 bits
  4119. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4120. %@TE:   6   421 02 14 17 45 @%
  4121.  
  4122. Because exponents are stored in an unsigned form, the exponent is biased by
  4123. half its possible value. For type %@AB@%float%@AE@%, the bias is 127; for type %@AB@%double%@AE@%,
  4124. it is 1,023; for type %@AB@%long double%@AE@%, it is 16,383. You can compute the actual
  4125. exponent value by subtracting the bias value from the exponent value.%@CR:C6A00040024 @%  %@NL@%
  4126. %@NL@%
  4127. The mantissa is stored as a binary fraction greater than or equal to 1 and
  4128. less than 2. For types %@AB@%float %@AE@%and %@AB@%double%@AE@%, there is an implied leading 1 in
  4129. the mantissa in the most-significant bit position, so the mantissas are
  4130. actually 24 and 53 bits long, respectively, even though the most-significant
  4131. bit is never stored in memory.  %@NL@%
  4132. %@NL@%
  4133. Instead of the storage method just described, the floating-point package can
  4134. store binary floating-point numbers as denormalized numbers. Denormalized
  4135. numbers are nonzero floating-point numbers with reserved exponent values in
  4136. which the most-significant bit of the mantissa is zero. By using
  4137. denormalized format, the range of a floating-point number can be extended at
  4138. the cost of precision. You cannot control whether a floating-point number is
  4139. represented in normalized or denormalized form; the floating-point package
  4140. determines the representation. The floating-point packages never use
  4141. denormalized form unless the exponent becomes less than the minimum that can
  4142. be represented in a normalized form.%@CR:C6A00040025 @%%@CR:C6A00040026 @%  %@NL@%
  4143. %@NL@%
  4144. Table 4.3 shows the minimum and maximum value you can store in variables of
  4145. each floating-point type. The values listed in this table apply only to
  4146. normalized floating-point numbers; denormalized floating-point numbers have
  4147. a smaller minimum value. Note that numbers retained in 80%@AI@%x%@AE@%87 registers are
  4148. always represented in 80-bit normal form; numbers can only be represented in
  4149. denormal form when stored in 32- or 64-bit floating-point variables (type
  4150. %@AB@%float%@AE@% and type %@AB@%long%@AE@%).%@CR:C6A00040027 @%%@CR:C6A00040028 @%  %@NL@%
  4151. %@NL@%
  4152. %@AB@%Table 4.3  %@AB@%Range of Floating-Point Types%@AE@%%@AE@%
  4153.  
  4154. %@TH:   6   527 02 14 31 31 @%
  4155. Type          Minimum Value                  Maximum Value
  4156. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4157. %@AB@%float%@AE@%         1.175494351 E - 38             3.402823466 E + 38
  4158. %@AB@%double%@AE@%        2.2250738585072014 E - 308     1.7976931348623158 E + 308
  4159. %@AB@%long double%@AE@%   3.362103143112093503 E - 4932  1.189731495357231765 E + 4932
  4160. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4161. %@TE:   6   527 02 14 31 31 @%
  4162.  
  4163. If precision is less of a concern than storage, consider using type %@AB@%float%@AE@%
  4164. for floating-point variables. Conversely, if precision is the most important
  4165. criterion, use type %@AB@%long double%@AE@%.%@CR:C6A00040029 @%%@CR:C6A00040030 @%  %@NL@%
  4166. %@NL@%
  4167. %@AU@% Microsoft C observes type-widening rules.%@CR:C6A00040031 @%%@AE@%  %@NL@%
  4168. %@NL@%
  4169. Floating-point variables can be promoted to a type of greater significance
  4170. (for example, from type %@AB@%float%@AE@% to type %@AB@%double%@AE@%). Promotion often occurs when
  4171. you perform arithmetic on floating-point variables. This arithmetic is
  4172. always done in as high a degree of precision as the variable with the
  4173. highest degree of precision. For example, consider the following type
  4174. declarations:%@CR:C6A00040032 @%%@CR:C6A00040033 @%  %@NL@%
  4175. %@NL@%
  4176. %@AS@%  float f_short;
  4177. %@AS@%  double f_long;
  4178. %@AS@%  long double f_longer;
  4179. %@AS@%  
  4180. %@AS@%  f_short = f_short * f_long;%@AE@%%@NL@%
  4181. %@NL@%
  4182. In the preceding example, the variable %@AS@% f_short %@AE@% is promoted to type %@AB@%double%@AE@%
  4183. and multiplied by %@AS@% f_long%@AE@%; then the result is rounded to type %@AB@%float %@AE@%before
  4184. being assigned to %@AS@% f_short%@AE@%.  %@NL@%
  4185. %@NL@%
  4186. In the example below (which uses the declarations from the preceding
  4187. example), the arithmetic is done in %@AB@%float%@AE@% (32-bit) precision on the
  4188. variables; the result is then promoted to type %@AB@%long double%@AE@%.  %@NL@%
  4189. %@NL@%
  4190. %@AS@%  f_longer = f_short * f_short;%@AE@%%@NL@%
  4191. %@NL@%
  4192. %@NL@%
  4193. %@3@%%@CR:C6A00040034 @%%@AB@%4.1.2  Declaring Functions that Return Floating-Point Types%@CR:C6A00040035 @%%@AE@%%@EH@%%@NL@%
  4194. %@NL@%
  4195. You can declare functions that return the floating-point types %@AB@%float%@AE@%,
  4196. %@AB@%double%@AE@%, and %@AB@%long double%@AE@%. Functions that return types %@AB@%float%@AE@% or %@AB@%double%@AE@% do not
  4197. place their return values in registers; they place their return values in a
  4198. global location called the floating-point accumulator ( fac).  %@NL@%
  4199. %@NL@%
  4200. When declaring a function as a floating-point type in a multithreaded
  4201. program for OS/2, you should use the %@AB@%_pascal%@AE@% keyword to specify the
  4202. FORTRAN/Pascal calling convention. Declaring the function as %@AB@%_pascal%@AE@% causes
  4203. the return value to be placed on the stack, rather than in the
  4204. floating-point accumulator, %@AB@% fac%@AE@%.  %@NL@%
  4205. %@NL@%
  4206. %@AU@% You can write re-entrant functions that return floating-point types.%@AE@%  %@NL@%
  4207. %@NL@%
  4208. Using the current thread's private stack to return values allows you to
  4209. write re-entrant functions by eliminating possible contention between
  4210. threads for the floating-point accumulator.%@CR:C6A00040036 @%%@CR:C6A00040037 @%%@CR:C6A00040038 @%%@CR:C6A00040039 @%%@CR:C6A00040040 @%%@CR:C6A00040041 @%%@CR:C6A00040042 @%  %@NL@%
  4211. %@NL@%
  4212. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4213. NOTE
  4214.  
  4215. %@AI@%Functions that return type %@AB@%long double%@AE@%%@AI@% always place their return values on
  4216. %@AI@%the stack. You need not use the %@AE@%%@AI@%%@AB@%_pascal%@AE@%%@AE@%%@AI@% keyword with functions declared as
  4217. %@AI@%%@AE@%%@AI@%%@AB@%long double%@AE@%%@AE@%%@AI@%.%@AE@%%@AE@%%@NL@%
  4218. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  4219. %@NL@%
  4220. %@NL@%
  4221. %@2@%%@CR:C6A00040043 @%%@AB@%4.2  C Run-Time Library Support of Type long double%@CR:C6A00040044 @%%@CR:C6A00040045 @%%@CR:C6A00040046 @%%@AE@%%@EH@%%@NL@%
  4222. %@NL@%
  4223. All of the Microsoft C run-time libraries support type %@AB@%long double%@AE@%. Each of
  4224. the normal floating-point math functions has a special version that supports
  4225. type %@AB@%long double%@AE@%. These functions have the same name as the functions that
  4226. support type %@AB@%float %@AE@%and type %@AB@%double%@AE@%, except that they end with %@AB@%l%@AE@%. For
  4227. example, the function that returns the absolute value of a variable of type
  4228. %@AB@%float %@AE@%or type %@AB@%double %@AE@%is %@AB@%fabs%@AE@%. The %@AB@%long double %@AE@%equivalent function is %@AB@%fabsl%@AE@%.
  4229. The two exceptions to this rule are the %@AB@%_atold%@AE@% and %@AB@%_strtodl%@AE@% functions.  %@NL@%
  4230. %@NL@%
  4231. %@NL@%
  4232. %@2@%%@CR:C6A00040047 @%%@AB@%4.3  Summary of Math Packages%@AE@%%@EH@%%@NL@%
  4233. %@NL@%
  4234. The Microsoft C compiler offers a choice of the following three math
  4235. packages for handling floating-point operations:%@CR:C6A00040048 @%  %@NL@%
  4236. %@NL@%
  4237. %@NL@%
  4238.   1.  Emulator (default)%@CR:C6A00040049 @%%@CR:C6A00040050 @%%@NL@%
  4239. %@NL@%
  4240.   2.  Math coprocessor (a library that supports the Intel 80%@AI@%x%@AE@%87 family of
  4241.       math coprocessors)%@CR:C6A00040051 @%%@CR:C6A00040052 @%%@NL@%
  4242. %@NL@%
  4243.   3.  Alternate math %@NL@%
  4244. %@NL@%
  4245. %@NL@%
  4246. When you install Microsoft C, the SETUP program allows you to build combined
  4247. libraries. These libraries include the floating-point math library that you
  4248. choose. Any programs linked with that library use the math package included
  4249. in the library; you must use the appropriate PWB or CL option to make sure
  4250. that the library you want is used at link time.%@CR:C6A00040053 @%  %@NL@%
  4251. %@NL@%
  4252. The following descriptions of these math packages are designed to help you
  4253. choose the appropriate math option for your needs when you build a library
  4254. using SETUP. For more information about SETUP and about building combined
  4255. libraries, see %@AI@%Installing and Using the Microsoft C Professional Development
  4256. %@AI@%System%@AE@%.%@CR:C6A00040054 @%  %@NL@%
  4257. %@NL@%
  4258. Note that this chapter does not describe mode-specific libraries. For
  4259. simplicity, the base names of libraries are noted in their default form;
  4260. that is %@AI@%m%@AE@%LIBC%@AI@%f%@AE@%.LIB, where %@AI@%m%@AE@% is the model designator and  %@AI@%f%@AE@% is the
  4261. floating-point math package designator. For information about mode-specific
  4262. libraries, see Chapter 14, "Building OS/2 Applications," or %@AI@%Installing and
  4263. %@AI@%Using the Microsoft C Professional Development System%@AE@%.  %@NL@%
  4264. %@NL@%
  4265. %@NL@%
  4266. %@3@%%@CR:C6A00040055 @%%@AB@%4.3.1  Emulator Package%@CR:C6A00040056 @%%@CR:C6A00040057 @%%@AE@%%@EH@%%@NL@%
  4267. %@NL@%
  4268. Programs created using the emulator math package automatically detect and
  4269. use an 80%@AI@%x%@AE@%87 numeric coprocessor if one is installed. If no coprocessor is
  4270. installed, these 80%@AI@%x%@AE@%87 instructions are carried out in software. The
  4271. emulator package is the default math package; SETUP uses it if you do not
  4272. explicitly choose another package. Also, the emulator math option is the
  4273. option selected by default by the compiler if no other floating-point math
  4274. option is specified.%@CR:C6A00040058 @%%@CR:C6A00040059 @%%@CR:C6A00040060 @%  %@NL@%
  4275. %@NL@%
  4276. Use the emulator math package to maximize accuracy on systems without math
  4277. coprocessors or if your program will be run on some systems with
  4278. coprocessors and some systems without coprocessors.%@CR:C6A00040061 @%  %@NL@%
  4279. %@NL@%
  4280. The emulator package performs basic operations to the same degree of
  4281. accuracy as a math coprocessor. However, the emulator routines used for
  4282. transcendental math functions (such as %@AB@%sin%@AE@%, %@AB@%cos%@AE@%, %@AB@%tan%@AE@%) differ slightly from
  4283. the corresponding functions performed on a coprocessor. This difference can
  4284. cause a slight discrepancy (usually within two bits) between the results of
  4285. these operations when performed with the software emulation instead of with
  4286. a math coprocessor.%@CR:C6A00040062 @%  %@NL@%
  4287. %@NL@%
  4288. %@AU@% When you use the emulator package, some floating-point exceptions are
  4289. %@AU@%masked.%@CR:C6A00040063 @%%@AE@%  %@NL@%
  4290. %@NL@%
  4291. When you use a math coprocessor or the emulator floating-point math package,
  4292. interrupt-enable, precision, underflow, and denormalized-operand exceptions
  4293. are masked by default. The remaining floating-point exceptions are unmasked.
  4294. See the discussion of the %@AB@%_control87%@AE@% function in on-line help for more
  4295. information about 80%@AI@%x%@AE@%87 floating-point exceptions.%@CR:C6A00040064 @%%@CR:C6A00040065 @%%@CR:C6A00040066 @%%@CR:C6A00040067 @%%@CR:C6A00040068 @%%@CR:C6A00040069 @%  %@NL@%
  4296. %@NL@%
  4297. %@NL@%
  4298. %@3@%%@CR:C6A00040070 @%%@AB@%4.3.2  Math Coprocessor Package%@CR:C6A00040071 @%%@CR:C6A00040072 @%%@AE@%%@EH@%%@NL@%
  4299. %@NL@%
  4300. The math coprocessor package utilizes the 80%@AI@%x%@AE@%87 math coprocessor exclusively
  4301. for floating-point calculations. If you use the math coprocessor package,
  4302. the machine on which your application is to run must have an 80%@AI@%x%@AE@%87
  4303. coprocessor to perform floating-point operations. This package gives you the
  4304. fastest, smallest programs possible for handling floating-point math.%@CR:C6A00040073 @%%@CR:C6A00040074 @%  %@NL@%
  4305. %@NL@%
  4306. %@NL@%
  4307. %@3@%%@CR:C6A00040075 @%%@AB@%4.3.3  Alternate Math Package%@CR:C6A00040076 @%%@CR:C6A00040077 @%%@CR:C6A00040078 @%%@CR:C6A00040079 @%%@AE@%%@EH@%%@NL@%
  4308. %@NL@%
  4309. The alternate math package gives you the smallest and fastest programs
  4310. possible without a coprocessor. However, the program results are not as
  4311. accurate as results given by the emulator package.  %@NL@%
  4312. %@NL@%
  4313. The alternate math package uses the same format as the IEEE standard-format
  4314. numbers with less precision and weaker error checking. The alternate math
  4315. package does not support infinities, NANs ("not a number"), and denormal
  4316. numbers.%@CR:C6A00040080 @%%@CR:C6A00040081 @%%@CR:C6A00040082 @%%@CR:C6A00040083 @%%@CR:C6A00040084 @%  %@NL@%
  4317. %@NL@%
  4318. You must always use the alternate math package when developing routines that
  4319. are to be placed in an OS/2 dynamic-link library (DLL) using LLIBCDLL.LIB.
  4320. Do not, however, use the alternate math package for building the C run-time
  4321. DLL using CDLLOBJS.LIB; instead, use the emulator math package. For more
  4322. information about creating dynamic-link libraries for OS/2, see Chapter 16.%@CR:C6A00040085 @%%@CR:C6A00040086 @%
  4323. %@NL@%
  4324. %@NL@%
  4325. %@NL@%
  4326. %@2@%%@CR:C6A00040087 @%%@AB@%4.4  Selecting Floating-Point Options (/FP)%@AE@%%@EH@%%@NL@%
  4327. %@NL@%
  4328. You can select a floating-point library and the method of accessing
  4329. floatingpoint routines by setting options in PWB or by specifying
  4330. command-line options to CL. You can choose between the emulator, alternate,
  4331. or math coprocessor library. You can also access the floating-point routines
  4332. by issuing a function call (or calls) or by generating in-line 80%@AI@%x%@AE@%87
  4333. instructions to execute the floating-point operation. The smallest and the
  4334. fastest floating-point math option is the in-line math coprocessor package
  4335. because the compiler generates true 80%@AI@%x%@AE@%87 coprocessor instructions. If,
  4336. however, you cannot depend on the target computer having a coprocessor, you
  4337. must use either the emulator or alternate math options.%@CR:C6A00040088 @%%@CR:C6A00040089 @%%@CR:C6A00040090 @%  %@NL@%
  4338. %@NL@%
  4339. To specify floating-point options on the CL command line, you must specify
  4340. an option from the list in Table 4.4. You specify these options to CL
  4341. starting with the floating-point option string /FP.  %@NL@%
  4342. %@NL@%
  4343. Based on the floating-point option and the memory-model option you choose,
  4344. the compiler embeds a library name in the object file that it creates. This
  4345. library is then considered the default library; that is, the linker searches
  4346. in the standard places for a library with that name. If it finds a library
  4347. with that name, the linker uses the library to resolve external references
  4348. in the object file being linked. Otherwise, it displays a message indicating
  4349. that it could not find the library.  %@NL@%
  4350. %@NL@%
  4351. This mechanism allows the linker to automatically link object files with the
  4352. appropriate library. However, you can link with a different library in some
  4353. cases. See Table 4.4 and Section 4.5, "Library Considerations for
  4354. Floating-Point Options," for more information about linking with different
  4355. libraries.  %@NL@%
  4356. %@NL@%
  4357. Table 4.4 summarizes the floating-point options and their effects. These
  4358. options are described in detail in the following sections.  %@NL@%
  4359. %@NL@%
  4360. %@AB@%Table 4.4  %@AB@%Summary of Floating-Point Options%@AE@%%@AE@%
  4361.  
  4362. %@TH:  51  3718 03 23 15 15 21 17 @%
  4363. Option for CL for PWB  Combined Use                                       Libraries 
  4364.                        of Method      Effect         Coprocessor          Selected
  4365. %@AB@%───────────────────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4366. /FPi                   In-line        Default;       Uses coprocessor if  %@AI@%m%@AE@%LIBCE.LIB%@AU@%(2)%@AE@%
  4367. In-Line                               larger than    present%@AU@%(1)%@AE@%           
  4368. Emulation                             /FPi87, but                         
  4369.                                       can work                            
  4370.                                       without a                           
  4371.                                       coprocessor;                        
  4372.                                       most                                
  4373.                                       efficient way                       
  4374.                                       to get                              
  4375.                                       maximum                             
  4376.                                       precision                           
  4377.                                       without a                           
  4378.                                       coprocessor                         
  4379.  
  4380. /FPi87                 In-line        Smallest and   Requires             %@AI@%m%@AE@%LIBC7.LIB
  4381. In-Line Math                          fastest        coprocessor          
  4382. Coprocessor                           option                              
  4383.                                       available                           
  4384.                                       with a                              
  4385.                                       coprocessor                         
  4386.  
  4387. /FPc                   Calls          Slower than    Uses coprocessor if  %@AI@%m%@AE@%LIBCE.LIB%@AU@%(2,3)%@AE@%
  4388. Calls to                              /FPi, but      present%@AU@%(1)%@AE@%           
  4389. Emulator                              allows use of                       
  4390.                                       alternate                           
  4391.                                       math library                        
  4392.                                       at link time                        
  4393.  
  4394. /FPc87                 Calls          Slower than    Requires             %@AI@%m%@AE@%LIBC7.LIB%@AU@%(3,4)%@AE@%
  4395. Calls to Math                         /FPi87, but    coprocessor unless   
  4396. Coprocessor                           allows use of  library changed at   
  4397.                                       alternate      link time%@AU@%(5)%@AE@%         
  4398.                                       math library                        
  4399.                                       at link time                        
  4400.  
  4401. /FPa                   Calls          Fastest and    Ignores              %@AI@%m%@AE@%LIBCA.LIB%@AU@%(2,4)%@AE@%
  4402. Alternate Math                        smallest       coprocessor          
  4403.                                       option                              
  4404.                                       available                           
  4405.                                       without a                           
  4406.                                       coprocessor,                        
  4407.                                       but                                 
  4408.                                       sacrifices                          
  4409.                                       some accuracy                       
  4410.                                       for speed                           
  4411.  
  4412. %@AB@%───────────────────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4413.  
  4414. %@TE:  51  3718 03 23 15 15 21 17 @%
  4415.  
  4416. %@AU@%(1) %@AE@% Use of the coprocessor can be suppressed by setting NO87. 
  4417. %@AU@%(2) %@AE@% Can be linked explicitly with %@AI@%m%@AE@%LIBC7.LIB at link time. 
  4418. %@AU@%(3) %@AE@% Can be linked explicitly with %@AI@%m%@AE@%LIBCA.LIB at link time. 
  4419. %@AU@%(4) %@AE@% Can be linked explicitly with %@AI@%m%@AE@%LIBCE.LIB at link time. 
  4420. %@AU@%(5) %@AE@% Use of the coprocessor can be suppressed by setting NO87 if you change
  4421. to the emulator library at link time. %@NL@%
  4422. %@NL@%
  4423. %@NL@%
  4424. Optimizations such as constant propagation and constant subexpression
  4425. elimination can cause some expressions to be evaluated at compile time. Such
  4426. evaluations always use IEEE format and are unaffected by the floating-point
  4427. option you choose. For more information about optimizing, see Chapter 1,
  4428. "Optimizing C Programs."%@CR:C6A00040091 @%%@CR:C6A00040092 @%%@CR:C6A00040093 @%  %@NL@%
  4429. %@NL@%
  4430. %@AU@% You can specify floatingpoint options in the Programmer's WorkBench.%@AE@%  %@NL@%
  4431. %@NL@%
  4432. To specify floating-point options when using the Programmer's WorkBench, you
  4433. must modify the C Global Build Options (available on the Options menu). In
  4434. the C Global Build Options dialog box, select one of the following
  4435. floating-point math options:%@CR:C6A00040094 @%%@CR:C6A00040095 @%%@CR:C6A00040096 @%  %@NL@%
  4436. %@NL@%
  4437. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  4438. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4439. Emulation Calls %@CR:C6A00040097 @%                  Generates calls; makes emulator math 
  4440.                                   library the
  4441.                                   default (/FPc)
  4442.  
  4443. 80%@AI@%x%@AE@%87 Calls %@CR:C6A00040098 @%                      Generates calls; makes math coprocessor 
  4444.                                   library the default (/FPc87)
  4445.  
  4446. Fast Alternate Math %@CR:C6A00040099 @%              Generates calls; makes alternate math 
  4447.                                   library the
  4448.                                   default (/FPa)
  4449.  
  4450. Inline Emulation %@CR:C6A00040100 @%                 Generates in-line instructions; makes 
  4451.                                   emulator math library the default 
  4452.                                   (/FPi); this is the default option
  4453.  
  4454. Inline 80x87                      Generates in-line instructions; selects 
  4455. Instructions %@CR:C6A00040101 @%                     math coprocessor library (/FPi87)
  4456.  
  4457. %@NL@%
  4458. %@3@%%@CR:C6A00040102 @%%@AB@%4.4.1  In-Line Emulator Option (/FPi)%@CR:C6A00040103 @%%@CR:C6A00040104 @%%@CR:C6A00040105 @%%@AE@%%@EH@%%@NL@%
  4459. %@NL@%
  4460. The in-line emulator option (/FPi) generates in-line instructions for an
  4461. 80%@AI@%x%@AE@%87 coprocessor and places the name of the emulator library (%@AI@%m%@AE@%LIBCE.LIB)
  4462. in the object file. At link time, you can specify the math coprocessor
  4463. library (%@AI@%m%@AE@%LIBC7.LIB) instead. If you do not choose a floating-point option,
  4464. the compiler uses the in-line emulator option by default.%@CR:C6A00040106 @%  %@NL@%
  4465. %@NL@%
  4466. The in-line emulator option is useful if you cannot be sure that an 80%@AI@%x%@AE@%87
  4467. coprocessor will be available on the target computer. Programs compiled
  4468. using the in-line emulator option work as described below:  %@NL@%
  4469. %@NL@%
  4470. %@NL@%
  4471.   ■   If a coprocessor is present at run time, the program uses the
  4472.       coprocessor.%@NL@%
  4473. %@NL@%
  4474.   ■   If no coprocessor is present, the program uses the emulator. In this
  4475.       case, the in-line emulator option offers the most efficient way to get
  4476.       maximum precision in floating-point results.%@NL@%
  4477. %@NL@%
  4478. %@NL@%
  4479. When you use the in-line emulator option, the compiler does not generate
  4480. in-line 80%@AI@%x%@AE@%87 instructions. For real-mode code, the compiler generates
  4481. software interrupts to library code, which then fixes up the interrupts to
  4482. use either the emulator or the coprocessor, depending on whether a
  4483. coprocessor is present. For protected-mode code, the compiler generates no
  4484. such interrupts; it generates 80%@AI@%x%@AE@%87 instructions. If the target computer
  4485. does not have a coprocessor, an "unsupported extension" exception occurs,
  4486. which is vectored to library code. If you want true in-line 80%@AI@%x%@AE@%87
  4487. instructions, use the in-line math coprocessor option (/FPi87).  %@NL@%
  4488. %@NL@%
  4489. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4490. NOTE
  4491.  
  4492. %@AI@%In an OS/2 dynamic-link library built with LLIBCDLL.LIB, you cannot use code
  4493. %@AI@%that requires the emulator library. You must use the alternate math library
  4494. %@AI@%instead.%@CR:C6A00040107 @%%@AE@%%@NL@%
  4495. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  4496. %@NL@%
  4497. %@NL@%
  4498. %@3@%%@CR:C6A00040108 @%%@AB@%4.4.2  In-Line Math Coprocessor Instructions Option (/FPi87)%@CR:C6A00040109 @%%@CR:C6A00040110 @%%@CR:C6A00040111 @%%@AE@%%@EH@%%@NL@%
  4499. %@NL@%
  4500. The in-line math coprocessor instructions option (/FPi87) instructs the
  4501. compiler to place 80%@AI@%x%@AE@%87 coprocessor instructions in your code for many math
  4502. operations. It also causes the name of a math coprocessor library
  4503. (%@AI@%m%@AE@%LIBC7.LIB) to be embedded in the object file.%@CR:C6A00040112 @%  %@NL@%
  4504. %@NL@%
  4505. If you use the in-line math coprocessor instructions option and link with
  4506. the library %@AI@%m%@AE@%LIBC7.LIB, an 80%@AI@%x%@AE@%87 coprocessor must be present at run time, or
  4507. the program fails and the following error message is displayed:  %@NL@%
  4508. %@NL@%
  4509. %@AS@%  run-time error R6002
  4510. %@AS@%  - floating point not loaded%@AE@%%@NL@%
  4511. %@NL@%
  4512. Compiling with the in-line math coprocessor instructions option results in
  4513. the smallest, fastest programs possible for handling floating-point results.%@CR:C6A00040113 @%%@CR:C6A00040114 @%
  4514. %@NL@%
  4515. %@NL@%
  4516. %@NL@%
  4517. %@3@%%@CR:C6A00040115 @%%@AB@%4.4.3  Calls to Emulator Option (/FPc)%@CR:C6A00040116 @%%@CR:C6A00040117 @%%@AE@%%@EH@%%@NL@%
  4518. %@NL@%
  4519. The calls to emulator option (/FPc) generates floating-point calls to the
  4520. emulator library and places the names of an emulator library (%@AI@%m%@AE@%LIBCE.LIB) in
  4521. the object file. At link time, you can specify a math coprocessor library
  4522. (%@AI@%m%@AE@%LIBC7.LIB) or an alternate math library (%@AI@%m%@AE@%LIBCA.LIB) instead. Thus, the
  4523. calls to emulator option gives you more flexibility in the libraries you can
  4524. use for linking than the in-line emulator option.  %@NL@%
  4525. %@NL@%
  4526. Using the calls to emulator option is also recommended in the following
  4527. cases:  %@NL@%
  4528. %@NL@%
  4529. %@NL@%
  4530.   ■   If you compile modules that perform floating-point operations and plan
  4531.       to include these modules in a library%@CR:C6A00040118 @%%@NL@%
  4532. %@NL@%
  4533.   ■   If you compile modules that you want to link with libraries other than
  4534.       the libraries provided with Microsoft C%@CR:C6A00040119 @%%@NL@%
  4535. %@NL@%
  4536. %@NL@%
  4537. You cannot link with an alternate math library if your program uses the
  4538. intrinsic forms of floating-point library routines (that is, if you have
  4539. compiled the program with the /Oi or /Ox option, selected the Generate
  4540. Intrinsic Functions option from the Debug Build Options or Release Build
  4541. Options dialog box in the Programmer's WorkBench, or specified math
  4542. functions in an %@AB@%intrinsic%@AE@% pragma).  %@NL@%
  4543. %@NL@%
  4544. %@NL@%
  4545. %@3@%%@CR:C6A00040120 @%%@AB@%4.4.4  Calls to Math Coprocessor Option (/FPc87)%@CR:C6A00040121 @%%@CR:C6A00040122 @%%@AE@%%@EH@%%@NL@%
  4546. %@NL@%
  4547. The calls to math coprocessor option (/FPc87) generates function calls to
  4548. routines in the math coprocessor library (%@AI@%m%@AE@%LIBC7.LIB) that issue the
  4549. corresponding 80%@AI@%x%@AE@%87 instructions. As with the in-line math coprocessor
  4550. instructions option (/FPi87), at link time you can choose to link with an
  4551. emulator library (%@AI@%m%@AE@%LIBCE.LIB). However, /FPc offers more flexibility in
  4552. choosing libraries, since you can change your mind and link with the
  4553. appropriate alternate math library as well (%@AI@%m%@AE@%LIBCA.LIB).  %@NL@%
  4554. %@NL@%
  4555. The disadvantages of using the calls to math coprocessor option as opposed
  4556. to the in-line coprocessor option are the following:  %@NL@%
  4557. %@NL@%
  4558. %@NL@%
  4559.   ■   Your executable size is larger because a call requires more
  4560.       instructions than a true coprocessor instruction.%@CR:C6A00040123 @%%@NL@%
  4561. %@NL@%
  4562.   ■   Your program does not execute as fast because you must issue a
  4563.       function call for each floating-point operation.%@CR:C6A00040124 @%%@NL@%
  4564. %@NL@%
  4565. %@NL@%
  4566. You cannot link with an alternate math library if your program uses the
  4567. intrinsic forms of floating-point library routines (that is, if you have
  4568. compiled the program with the /Oi or /Ox option, selected the Generate
  4569. Intrinsic Functions option from the Debug Build Options or Release Build
  4570. Options dialog box in the Programmer's WorkBench, or specified math
  4571. functions in an %@AB@%intrinsic%@AE@% pragma).  %@NL@%
  4572. %@NL@%
  4573. You must have a math coprocessor installed to run programs compiled with the
  4574. /FPc option and linked with a math coprocessor library. Otherwise, the
  4575. program fails and the following error message is displayed:  %@NL@%
  4576. %@NL@%
  4577. %@AS@%  run-time error R6002
  4578. %@AS@%  - floating point not loaded%@AE@%%@NL@%
  4579. %@NL@%
  4580. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4581. NOTE
  4582.  
  4583. %@AI@%Certain optimizations are not performed when you use the calls to math
  4584. %@AI@%coprocessor option. This can reduce the efficiency of your code; also, since
  4585. %@AI@%arithmetic of different precision can result, there may be slight
  4586. %@AI@%differences in your results.%@CR:C6A00040125 @%%@AE@%%@NL@%
  4587. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  4588. %@NL@%
  4589. %@NL@%
  4590. %@3@%%@CR:C6A00040126 @%%@AB@%4.4.5  Use Alternate Math Option (/FPa)%@CR:C6A00040127 @%%@CR:C6A00040128 @%%@CR:C6A00040129 @%%@AE@%%@EH@%%@NL@%
  4591. %@NL@%
  4592. The use alternate math option (/FPa) generates floating-point calls and
  4593. selects the alternate math library for the appropriate memory model
  4594. (%@AI@%m%@AE@%LIBCA.LIB). Calls to this library provide the fastest and smallest option
  4595. for code intended to run on a machine without an 80%@AI@%x%@AE@%87 coprocessor. With
  4596. this option, you can choose an emulator library (%@AI@%m%@AE@%LIBCE.LIB) or a math
  4597. coprocessor library (%@AI@%m%@AE@%LIBC7.LIB) at link time.%@CR:C6A00040130 @%%@CR:C6A00040131 @%  %@NL@%
  4598. %@NL@%
  4599. You cannot link with an alternate math library if your program uses the
  4600. intrinsic forms of floating-point library routines (that is, if you have
  4601. compiled the program with the /Oi or /Ox option, selected the Generate
  4602. Intrinsic Functions from the Debug Build Options or Release Build Options
  4603. dialog box in the Programmer's WorkBench, or specified math functions in an
  4604. %@AB@%intrinsic%@AE@% pragma).  %@NL@%
  4605. %@NL@%
  4606. %@NL@%
  4607. %@2@%%@CR:C6A00040132 @%%@AB@%4.5  Library Considerations for Floating-Point Options%@CR:C6A00040133 @%%@AE@%%@EH@%%@NL@%
  4608. %@NL@%
  4609. You may want to use libraries in addition to the default library for the
  4610. floating-point option you have chosen in your compile options. For example,
  4611. you may want to create your own libraries (or other collections of
  4612. subprograms in object-file form), then link these libraries at a later time
  4613. with object files that you have compiled using different options.  %@NL@%
  4614. %@NL@%
  4615. The following sections describe these cases and ways to handle them.
  4616. Although the discussion assumes that you are putting your object files into
  4617. libraries, the same considerations apply if you are simply using individual
  4618. object files.  %@NL@%
  4619. %@NL@%
  4620. %@NL@%
  4621. %@3@%%@CR:C6A00040134 @%%@AB@%4.5.1  Using One Standard Library for Linking%@AE@%%@EH@%%@NL@%
  4622. %@NL@%
  4623. You must use only one standard C run-time library when you link. You can
  4624. control which library is used in one of two ways:  %@NL@%
  4625. %@NL@%
  4626. %@NL@%
  4627.   1.  In the Programmer's WorkBench, add the name of the C run-time library
  4628.       file you want to the program list using the Edit Program List option
  4629.       from the Make menu. You must also modify the Linker Options (from the
  4630.       Make menu) by specifying No Default Library Search.%@NL@%
  4631. %@NL@%
  4632.   2.  From the LINK command line, give the /NODEFAULTLIBRARYSEARCH (/NOD)
  4633.       option and then specify the name of the combined library file you want
  4634.       to use in the %@AI@%link-libinfo%@AE@% field of the CL command line. This
  4635.       overrides the library names embedded in the object files.%@NL@%
  4636. %@NL@%
  4637. %@NL@%
  4638. %@NL@%
  4639. %@3@%%@CR:C6A00040135 @%%@AB@%4.5.2  In-Line Instructions or Calls%@CR:C6A00040136 @%%@CR:C6A00040137 @%%@AE@%%@EH@%%@NL@%
  4640. %@NL@%
  4641. When deciding on a floating-point option, you should decide whether you want
  4642. to use in-line instructions. If you do, compile with the in-line math
  4643. coprocessor instructions (/FPi87) or in-line emulator (/FPi) option.
  4644. Otherwise, compile for floating-point function calls using the calls to math
  4645. coprocessor (/FPc87), calls to emulator (/FPc), or alternate math (/FPa)
  4646. option.  %@NL@%
  4647. %@NL@%
  4648. If you choose to use in-line instructions for your precompiled object files,
  4649. you cannot link with an alternate math library (%@AI@%m%@AE@%LIBCA.LIB). However,
  4650. in-line instructions achieve the best performance from your programs on
  4651. machines that have an 80%@AI@%x%@AE@%87 coprocessor installed.%@CR:C6A00040138 @%  %@NL@%
  4652. %@NL@%
  4653. If you choose to use calls, your programs are slower, but at link time you
  4654. can switch to any standard C run-time library (that is, any library created
  4655. by the SETUP program) that supports the memory model you have chosen.  %@NL@%
  4656. %@NL@%
  4657. %@NL@%
  4658. %@2@%%@CR:C6A00040139 @%%@AB@%4.6  Compatibility between Floating-Point Options%@CR:C6A00040140 @%%@AE@%%@EH@%%@NL@%
  4659. %@NL@%
  4660. Each time you compile a source file, you can specify a floating-point
  4661. option. When you link two or more source files to produce an executable
  4662. program file, you must ensure that floating-point operations are handled
  4663. consistently and that the environment is set up properly to allow the linker
  4664. to find the required library.  %@NL@%
  4665. %@NL@%
  4666. If you are building libraries of C routines that contain floating-point
  4667. operations, the calls to emulator option (/FPc) provides the most
  4668. flexibility.%@CR:C6A00040141 @%%@CR:C6A00040142 @%  %@NL@%
  4669. %@NL@%
  4670. The examples that follow illustrate how you can link your program with a
  4671. library other than the default. The floating-point option and the substitute
  4672. library are compatible.  %@NL@%
  4673. %@NL@%
  4674. The example below compiles the program %@AS@% CALC.C %@AE@% with the medium-model
  4675. option (/AM). Because no floating-point option is specified, the default
  4676. in-line emulator option (/FPi) is used. The in-line emulator option
  4677. generates 80%@AI@%x%@AE@%87 instructions and specifies the emulator library MLIBCE.LIB
  4678. in the object file. The /LINK field specifies the /NODEFAULTLIBRARYSEARCH
  4679. (/NOD) option and the names of the medium-model math coprocessor library.
  4680. Specifying the math coprocessor library forces the program to use an 80%@AI@%x%@AE@%87
  4681. coprocessor; the program fails if a coprocessor is not present.  %@NL@%
  4682. %@NL@%
  4683. %@AS@%  CL /AM CALC.C /link MLIBC7 /NOD%@AE@%%@NL@%
  4684. %@NL@%
  4685. The example below compiles %@AS@% CALC.C %@AE@% using the small (default) memory model
  4686. and the alternate math option (/FPa). The /LINK field specifies the /NOD
  4687. option and the library SLIBCE.LIB. Specifying the emulator library causes
  4688. all floating-point calls to refer to the emulator library instead of the
  4689. alternate math library.  %@NL@%
  4690. %@NL@%
  4691. %@AS@%  CL /FPa CALC.C /link SLIBCE /NOD%@AE@%%@NL@%
  4692. %@NL@%
  4693. The example below compiles %@AS@% CALC.C %@AE@% with the calls to math coprocessor
  4694. option (/FPc87), which places the library name SLIBC7.LIB in the object
  4695. file. The /LINK field overrides this default-library specification by giving
  4696. the /NOD option and the name of the small-model alternate math library
  4697. (SLIBCA.LIB).  %@NL@%
  4698. %@NL@%
  4699. %@AS@%  CL /FPc87 CALC.C /link SLIBCA.LIB/NOD%@AE@%%@NL@%
  4700. %@NL@%
  4701. %@NL@%
  4702. %@2@%%@CR:C6A00040143 @%%@AB@%4.7  Using the NO87 Environment Variable%@CR:C6A00040144 @%%@CR:C6A00040145 @%%@AE@%%@EH@%%@NL@%
  4703. %@NL@%
  4704. Programs compiled using either the calls to emulator (/FPc) or the in-line
  4705. emulator (/FPi) option automatically use an 80%@AI@%x%@AE@%87 coprocessor at run time if
  4706. one is installed. You can override this and force the use of the software
  4707. emulator by setting an environment variable named NO87.%@CR:C6A00040146 @%%@CR:C6A00040147 @%%@CR:C6A00040148 @%%@CR:C6A00040149 @%%@CR:C6A00040150 @%%@CR:C6A00040151 @%  %@NL@%
  4708. %@NL@%
  4709. %@AU@% Use the NO87 environment variable to suppress use of the 80x87 coprocessor
  4710. %@AU@%at run time.%@AE@%  %@NL@%
  4711. %@NL@%
  4712. If NO87 is set to any value when the program is executed, use of the
  4713. coprocessor is suppressed. The value of the NO87 setting is printed on the
  4714. standard output as a message. The message is printed only if a coprocessor
  4715. is present and suppressed; if no coprocessor is present, no message appears.
  4716. If you don't want a message to be printed, set NO87 equal to one or more
  4717. spaces. A blank string for NO87 causes a blank line to be printed.  %@NL@%
  4718. %@NL@%
  4719. Note that only the presence or absence of the NO87 definition is important
  4720. in suppressing use of the coprocessor. The actual value of the NO87 setting
  4721. is used only for printing the message.  %@NL@%
  4722. %@NL@%
  4723. The NO87 variable takes effect with any program linked with an emulator
  4724. library (%@AI@%m%@AE@%LIBCE.LIB). It has no effect on programs linked with math
  4725. coprocessor libraries (%@AI@%m%@AE@%LIBC7.LIB) or programs linked with alternate math
  4726. libraries (%@AI@%m%@AE@%LIBCA.LIB).  %@NL@%
  4727. %@NL@%
  4728. When a program that uses an emulator library is executed and an 80%@AI@%x%@AE@%87
  4729. coprocessor is present, the example below causes the message %@AS@% Use of
  4730. %@AS@%coprocessor suppressed %@AE@% to appear.  %@NL@%
  4731. %@NL@%
  4732. %@AS@%  SET NO87=Use of coprocessor suppressed%@AE@%%@NL@%
  4733. %@NL@%
  4734. The syntax below sets the NO87 variable to the space character. Use of the
  4735. coprocessor is still suppressed, but no message is displayed.  %@NL@%
  4736. %@NL@%
  4737. %@AS@%  SET NO87=space%@AE@%%@NL@%
  4738. %@NL@%
  4739. %@NL@%
  4740. %@2@%%@CR:C6A00040152 @%%@AB@%4.8  Incompatibility Issues%@CR:C6A00040153 @%%@AE@%%@EH@%%@NL@%
  4741. %@NL@%
  4742. The exception handler in the libraries for 80%@AI@%x%@AE@%87 floating-point calculations
  4743. (%@AI@%m%@AE@%LIBCE.LIB and %@AI@%m%@AE@%LIBC7.LIB) is designed to work without modification on the
  4744. IBM PC family of computers and on closely compatible computers, including
  4745. the WANG(R) PC, the AT&T(R) 6300, and the Olivetti(R) personal computers.
  4746. Also, the libraries need not be modified for the Texas Instruments(R)
  4747. Professional Computer, even though it is not compatible. Any machine that
  4748. uses nonmaskable interrupts (NMI) for 80%@AI@%x%@AE@%87 exceptions will run with the
  4749. unmodified libraries. If your computer is not one of these, and if you are
  4750. not sure whether it is completely compatible, you may need to modify the
  4751. math coprocessor libraries.%@CR:C6A00040154 @%  %@NL@%
  4752. %@NL@%
  4753. All Microsoft languages that support 80%@AI@%x%@AE@%87 coprocessors intercept 80%@AI@%x%@AE@%87
  4754. exceptions in order to produce accurate results and properly detect error
  4755. conditions. To make the libraries work correctly on incompatible machines,
  4756. you can modify the libraries. To make this easier, an assembly-language
  4757. source file, EMOEM.ASM, is included on the C 6.0 distribution disk. Any
  4758. machine that sends the 80%@AI@%x%@AE@%87 exception to an 8259 Priority Interrupt
  4759. Controller (master or master/slave) can be supported by a simple table
  4760. change to the EMOEM.ASM module. The source file contains further
  4761. instructions about how to modify EMOEM.ASM, patch libraries, and executable
  4762. files.%@CR:C6A00040155 @%  %@NL@%
  4763. %@NL@%
  4764. %@NL@%
  4765. %@NL@%
  4766. %@NL@%
  4767. %@NL@%
  4768. %@NL@%
  4769. %@CR:C6A-Part 02 @%%@1@%%@AB@%PART II  Improving Programmer Productivity%@AE@%%@EH@%%@NL@%
  4770. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4771. %@NL@%
  4772.  The Microsoft C Professional Development System helps you write and debug
  4773. software rapidly.  %@NL@%
  4774. %@NL@%
  4775. Chapter 5 describes the quick compile and incremental compile options, both
  4776. of which can save you time when compiling programs. Chapter 5 also describes
  4777. the incremental linker, ILINK, which can save you time when you link your
  4778. application. Chapter 6 describes NMAKE, a powerful new program maintenance
  4779. utility that automates your program build process. Chapter 7 describes how
  4780. to build help files with HELPMAKE, the help-file maintenance utility. When
  4781. you need to share documentation in a readily accessible form, you can add it
  4782. to the Microsoft Advisor on-line help system using the information in
  4783. Chapter 7. Chapter 8 explains how to customize the Programmer's WorkBench to
  4784. make it a personalized development platform. Chapter 9 offers procedures
  4785. (and some tips) for using the CodeView debugger to find errors in your
  4786. programs.  %@NL@%
  4787. %@NL@%
  4788. %@NL@%
  4789. %@NL@%
  4790. %@NL@%
  4791. %@NL@%
  4792. %@NL@%
  4793. %@CR:C6A00050001 @%%@1@%%@AB@%Chapter 5  Compiling and Linking Quickly%@AE@%%@EH@%%@NL@%
  4794. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4795. %@NL@%
  4796. The fundamental processes of compiling and linking take time to perform. The
  4797. larger your application grows, the longer it takes to compile and link.  %@NL@%
  4798. %@NL@%
  4799. This chapter describes how you can speed up compiling by using the quick
  4800. compiler and incremental compile option, and how you can speed up linking by
  4801. using ILINK, the Incremental Linker.  %@NL@%
  4802. %@NL@%
  4803. %@NL@%
  4804. %@2@%%@CR:C6A00050002 @%%@AB@%5.1  Compiling Quickly%@AE@%%@EH@%%@NL@%
  4805. %@NL@%
  4806. This section describes two ways to speed up the compiling process: using the
  4807. quick compiler and using the incremental compile option.  %@NL@%
  4808. %@NL@%
  4809. %@NL@%
  4810. %@3@%%@CR:C6A00050003 @%%@AB@%5.1.1  Quick Compiler%@AE@%%@EH@%%@NL@%
  4811. %@NL@%
  4812. The Microsoft C Professional Development System includes two separate C
  4813. compilers: the full compiler and the quick compiler. If you don't specify
  4814. otherwise, your program is compiled by the full compiler.  %@NL@%
  4815. %@NL@%
  4816. You access the quick compiler by specifying the /qc command-line option for
  4817. CL or by selecting the Quick Compile option from the C Release Build or C
  4818. Debug Build Options dialogs in the PWB Options menu.  %@NL@%
  4819. %@NL@%
  4820. The quick compiler cannot perform as many optimizations as the full
  4821. compiler, but it is much faster. You can use it to save time during
  4822. development, whenever optimizations are not critical. When your application
  4823. is finished, you can compile with the full compiler, using all the desired
  4824. optimizations.  %@NL@%
  4825. %@NL@%
  4826. On-line help for the /qc option describes which optimizations the quick
  4827. compiler can perform.  %@NL@%
  4828. %@NL@%
  4829. %@NL@%
  4830. %@3@%%@CR:C6A00050004 @%%@AB@%5.1.2  Incremental Compile Option%@AE@%%@EH@%%@NL@%
  4831. %@NL@%
  4832. You can speed up compiling even more by compiling incrementally. Incremental
  4833. compilation means that the compiler compiles only those functions that have
  4834. changed since you last compiled.  %@NL@%
  4835. %@NL@%
  4836. The incremental compile option is available only with the quick compiler
  4837. (see the previous section). You can access it from within PWB or from the
  4838. DOS command line. Within PWB, select the Incremental Compile option in the C
  4839. Release Build dialog box or in the C Debug Build Options dialog box. From
  4840. the DOS command line, specify the /Gi option for CL.  %@NL@%
  4841. %@NL@%
  4842. The incremental compile option automatically triggers another time-saving
  4843. feature: the Incremental Linker, which is described in the next section.  %@NL@%
  4844. %@NL@%
  4845. %@NL@%
  4846. %@2@%%@CR:C6A00050005 @%%@AB@%5.2  Linking Quickly with ILINK%@AE@%%@EH@%%@NL@%
  4847. %@NL@%
  4848. %@AU@% ILINK links only those modules that have changed since the last link.%@AE@%  %@NL@%
  4849. %@NL@%
  4850. The Incremental Linker (ILINK) offers the same advantage in linking that the
  4851. incremental compile option offers in compiling. Rather than link every
  4852. module in an application, as LINK does, ILINK links only those modules that
  4853. have changed since the last link. The more modules your application
  4854. contains, the more time ILINK can potentially save.  %@NL@%
  4855. %@NL@%
  4856. In a normal development scenario, you use LINK at the beginning and end of
  4857. the process, and use ILINK in the middle. In the early stages of
  4858. development, when your application contains only a few modules, ILINK offers
  4859. no speed advantage over LINK. Once your application contains several
  4860. modules, you can save time by using ILINK.  %@NL@%
  4861. %@NL@%
  4862. %@AU@% You must link once with LINK to prepare for incremental linking.%@AE@%  %@NL@%
  4863. %@NL@%
  4864. To prepare for incremental linking, you must run LINK using /INCREMENTAL, as
  4865. described in Section 5.2.1. At the same time, you have the option of adding
  4866. padding bytes to code or data segments by specifying the /PADCODE and
  4867. /PADDATA options. Padding allows ILINK to expand a segment without relinking
  4868. the entire module in which it is contained.  %@NL@%
  4869. %@NL@%
  4870. Now you can link with ILINK during the rest of development. If changes in
  4871. your code require a full link, ILINK invokes LINK automatically. When the
  4872. application is finished, you link a last time with LINK to produce the final
  4873. executable file.  %@NL@%
  4874. %@NL@%
  4875. You can use ILINK with programs compiled for any memory model except tiny
  4876. model. (Memory models are described in Chapter 2, "Managing Memory.")
  4877. Typically, ILINK is not efficient for small- or compact-model programs
  4878. unless they were compiled with the incremental compile option, which is
  4879. described in Section 5.1.2.  %@NL@%
  4880. %@NL@%
  4881. %@NL@%
  4882. %@3@%%@CR:C6A00050006 @%%@AB@%5.2.1  Preparing for Incremental Linking%@AE@%%@EH@%%@NL@%
  4883. %@NL@%
  4884. There are three LINK options that relate to the use of ILINK. One of them
  4885. (/INCREMENTAL) is mandatory; the other two (/PADCODE and /PADDATA) are
  4886. optional. This section explains the LINK options that prepare for ILINK. See
  4887. on-line help for a complete list of LINK options.  %@NL@%
  4888. %@NL@%
  4889. %@NL@%
  4890. %@4@%%@AB@%The /INCREMENTAL Option%@AE@%%@EH@%%@NL@%
  4891. %@NL@%
  4892. The /INCREMENTAL (/INC) option prepares an object file for incremental
  4893. linking. You must always run LINK using this option before using ILINK. When
  4894. you specify /INC, the linker produces two extra files: a symbol file (.SYM)
  4895. and an ILINK support file (.ILK). The .SYM and .ILK files tell ILINK which
  4896. parts of the executable file need to be updated.  %@NL@%
  4897. %@NL@%
  4898. You must use /INCREMENTAL whenever you use the /PADCODE and /PADDATA
  4899. options, which are described below.  %@NL@%
  4900. %@NL@%
  4901. %@NL@%
  4902. %@4@%%@AB@%The /PADCODE Option%@AE@%%@EH@%%@NL@%
  4903. %@NL@%
  4904. The /PADCODE option causes LINK to add padding bytes at the end of a
  4905. module's code segment. The padding bytes leave room for the code segment to
  4906. grow in subsequent links, allowing ILINK to update only that module. You can
  4907. use the /PADCODE option only when /INC is also specified.  %@NL@%
  4908. %@NL@%
  4909. Code padding is usually necessary for programs using the small memory model.
  4910. It is also recommended for compact- or mixed-model programs. You do not need
  4911. to specify /PADCODE for other memory models (medium, large, or huge).%@CR:C6A00050007 @%%@CR:C6A00050008 @%  %@NL@%
  4912. %@NL@%
  4913. If you don't specify /PADCODE, LINK doesn't pad the code segment at all. To
  4914. add padding, specify the desired number of bytes. The optimum amount of
  4915. padding depends on how much your code changes from one link to the next. If
  4916. you expect to add only a little code, choose a relatively%@CR:C6A00050009 @% small amount of
  4917. padding, say 32 to 64 bytes. If ILINK issues the message  %@NL@%
  4918. %@NL@%
  4919. %@AS@%  padding exceeded%@AE@%%@NL@%
  4920. %@NL@%
  4921. and performs a full link more often than desired, increase the padding by a
  4922. small amount, say 32 bytes. In any case, remember that the total size of a
  4923. code segment, including padding bytes, cannot exceed 64K (65,535) bytes.  %@NL@%
  4924. %@NL@%
  4925. %@NL@%
  4926. %@4@%%@AB@%The /PADDATA Option%@AE@%%@EH@%%@NL@%
  4927. %@NL@%
  4928. Like /PADCODE, the /PADDATA option causes LINK to add padding bytes that
  4929. leave room for the segment to grow in subsequent links. However, the
  4930. /PADDATA option pads the end of the data segment rather than the code
  4931. segment. You can use /PADDATA only when /INC is also specified.  %@NL@%
  4932. %@NL@%
  4933. If you don't specify /PADDATA, LINK adds 16 bytes of padding by default. The
  4934. default padding amount should suffice in many cases, since public variables
  4935. are added less frequently than code. If you need more padding, specify the
  4936. desired number of bytes. Remember that the total size of a data segment,
  4937. including padding bytes, cannot exceed 64K (65,535) bytes.  %@NL@%
  4938. %@NL@%
  4939. %@NL@%
  4940. %@3@%%@CR:C6A00050010 @%%@AB@%5.2.2  Incremental Violations%@AE@%%@EH@%%@NL@%
  4941. %@NL@%
  4942. ILINK can generate two kinds of errors: real errors and incremental
  4943. violations. Real errors are errors such as undefined symbols that cannot be
  4944. resolved by a full link. If ILINK detects a real error, it displays an error
  4945. message (real errors are documented in on-line help).  %@NL@%
  4946. %@NL@%
  4947. Incremental violations are caused by code changes you have made that go
  4948. beyond the scope of incremental linking. When an incremental violation
  4949. occurs, ILINK invokes LINK automatically. The following sections describe
  4950. the incremental violations.  %@NL@%
  4951. %@NL@%
  4952. %@NL@%
  4953. %@4@%%@AB@%Changing Libraries%@AE@%%@EH@%%@NL@%
  4954. %@NL@%
  4955. An incremental violation occurs when a library changes. Furthermore, if an
  4956. altered module shares a code segment with a library, ILINK needs access to
  4957. the library as well as to the altered module.  %@NL@%
  4958. %@NL@%
  4959. If you add a function, procedure, or subroutine call to a library that has
  4960. never been called before, ILINK invokes LINK automatically.  %@NL@%
  4961. %@NL@%
  4962. %@NL@%
  4963. %@4@%%@AB@%Exceeding Code/Data Padding%@AE@%%@EH@%%@NL@%
  4964. %@NL@%
  4965. An incremental violation occurs if two or more modules contribute to the
  4966. same physical segment and either module exceeds its padding. The padding
  4967. allows the module to increase the specified number of bytes before another
  4968. full link is required.  %@NL@%
  4969. %@NL@%
  4970. %@NL@%
  4971. %@4@%%@AB@%Moving or Deleting Data Symbols%@AE@%%@EH@%%@NL@%
  4972. %@NL@%
  4973. An incremental violation occurs if a data symbol is moved or deleted. To add
  4974. new data symbols without requiring a full link, add the new symbols at the
  4975. end of all other data symbols in the module.  %@NL@%
  4976. %@NL@%
  4977. %@NL@%
  4978. %@4@%%@AB@%Deleting Code Symbols%@AE@%%@EH@%%@NL@%
  4979. %@NL@%
  4980. You can move or add code symbols, but an incremental violation occurs if you
  4981. delete any code symbols from a module. Code symbols can be moved within a
  4982. module but cannot be moved between modules.  %@NL@%
  4983. %@NL@%
  4984. %@NL@%
  4985. %@4@%%@AB@%Changing Segment Definitions%@AE@%%@EH@%%@NL@%
  4986. %@NL@%
  4987. An incremental violation results if you add, delete, or change the order of
  4988. segment definitions.  %@NL@%
  4989. %@NL@%
  4990. %@NL@%
  4991. %@4@%%@AB@%Adding CodeView(R) Debugger Information%@AE@%%@EH@%%@NL@%
  4992. %@NL@%
  4993. If you include CodeView debugger information for a module when you fully
  4994. link (by compiling and linking with CodeView debugger support), ILINK
  4995. supports CodeView debugger information for the module. ILINK maintains
  4996. symbolic information for current symbols, and it adds information for any
  4997. new symbols. However, if you try to add CodeView debugger information for a
  4998. module that did not previously have CodeView debugger support, an
  4999. incremental violation occurs. See Chapter 9, "Debugging C Programs with
  5000. CodeView," for more information about CodeView.  %@NL@%
  5001. %@NL@%
  5002. %@NL@%
  5003. %@NL@%
  5004. %@NL@%
  5005. %@NL@%
  5006. %@NL@%
  5007. %@CR:C6A00060001 @%%@1@%%@AB@%Chapter 6  Managing Development Projects with NMAKE%@AE@%%@EH@%%@NL@%
  5008. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5009. %@NL@%
  5010. The Microsoft Program-Maintenance Utility (NMAKE) is a sophisticated command
  5011. processor that can save time and simplify project management. By determining
  5012. which project files depend on others, NMAKE can automatically execute the
  5013. commands needed to update your project when any project file has changed.  %@NL@%
  5014. %@NL@%
  5015. The advantage of using NMAKE over simple batch files is that NMAKE does only
  5016. what is needed. You don't waste time rebuilding files that are already
  5017. up-to-date. NMAKE also has advanced features, such as macros, that help you
  5018. manage complex projects.  %@NL@%
  5019. %@NL@%
  5020. This chapter provides complete documentation for NMAKE. Information about
  5021. NMAKE is also available in on-line help. If you are familiar with MAKE, the
  5022. predecessor of NMAKE, be sure to read Section 6.9, "Differences Between
  5023. NMAKE and MAKE." There are some important differences between the two
  5024. utilities.  %@NL@%
  5025. %@NL@%
  5026. %@NL@%
  5027. %@2@%%@CR:C6A00060002 @%%@AB@%6.1  Overview of NMAKE%@AE@%%@EH@%%@NL@%
  5028. %@NL@%
  5029. NMAKE works by comparing the times and dates of two sets of files, which are
  5030. called "targets" and "dependents." A target is normally a file that you want
  5031. to create, such as an executable file. A dependent is a file used to create
  5032. a target, such as a C source file.  %@NL@%
  5033. %@NL@%
  5034. When you run NMAKE, it reads a "description file" that you supply. The
  5035. description file consists of one or more blocks. Each block typically lists
  5036. a target, the target's dependents, and the command that builds the target.
  5037. NMAKE compares the date and time of the target to those of its dependents.
  5038. If any dependent has changed more recently than the target, NMAKE updates
  5039. the target by executing the command listed in the block.  %@NL@%
  5040. %@NL@%
  5041. NMAKE's main purpose is to help you update applications quickly and simply.
  5042. However, it can execute any command, so it is not limited to compiling and
  5043. linking. NMAKE can also make backups, move files, and do many other project
  5044. management tasks.  %@NL@%
  5045. %@NL@%
  5046. %@NL@%
  5047. %@2@%%@CR:C6A00060003 @%%@AB@%6.2  The NMAKE Command%@AE@%%@EH@%%@NL@%
  5048. %@NL@%
  5049. When you run NMAKE, you can supply the description-file name and other
  5050. arguments using the following syntax:  %@NL@%
  5051. %@NL@%
  5052. %@AB@%NMAKE%@AE@% «%@AI@%options%@AE@%» «%@AI@%macros%@AE@%» «%@AI@%targets%@AE@%» «%@AI@%descriptfile%@AE@%»  %@NL@%
  5053. %@NL@%
  5054. All of the command-line fields are optional. If you don't supply any
  5055. arguments, NMAKE looks for a default description file named MAKEFILE and
  5056. follows various other defaults that are described in this chapter.  %@NL@%
  5057. %@NL@%
  5058. The %@AI@%options%@AE@% field lists NMAKE options, which are described in Section 6.4,
  5059. "Command-Line Options."  %@NL@%
  5060. %@NL@%
  5061. The %@AI@%macros%@AE@% field lists macro definitions, which allow you to replace text in
  5062. the description file. Macros are described in Section 6.3.3.  %@NL@%
  5063. %@NL@%
  5064. The %@AI@%targets%@AE@% field lists targets to build. If you do not list any targets,
  5065. NMAKE builds only the first target in the description file. (This is a
  5066. significant departure from the behavior of MAKE, NMAKE's predecessor. See
  5067. Section 6.9, "Differences between NMAKE and MAKE.")  %@NL@%
  5068. %@NL@%
  5069. The %@AI@%descriptfile%@AE@% field specifies a description file. If this field is
  5070. absent, NMAKE automatically looks for a file named MAKEFILE in the current
  5071. directory. You can also specify the description file with the /F option (for
  5072. information, see Section 6.4, "Command-Line Options").  %@NL@%
  5073. %@NL@%
  5074. Below is a typical NMAKE command:  %@NL@%
  5075. %@NL@%
  5076. %@AS@%  NMAKE /S "program = sample" sort.exe search.exe%@AE@%%@NL@%
  5077. %@NL@%
  5078. The command supplies four arguments: an option (/S), a macro definition
  5079. (%@AS@%"program = sample"%@AE@%), and two target specifications (%@AS@%sort.exe search.exe%@AE@%).  %@NL@%
  5080. %@NL@%
  5081. Because the command does not specify a description file, NMAKE looks for the
  5082. default description file, MAKEFILE. The /S option tells NMAKE to suppress
  5083. the display of commands as they are executed. The macro definition performs
  5084. a text substitution throughout the description file, replacing every
  5085. instance of %@AS@% program %@AE@% with %@AS@% sample%@AE@%. The target specifications tell NMAKE to
  5086. update the targets SORT.EXE and SEARCH.EXE.  %@NL@%
  5087. %@NL@%
  5088. %@NL@%
  5089. %@2@%%@CR:C6A00060004 @%%@AB@%6.3  NMAKE Description Files%@AE@%%@EH@%%@NL@%
  5090. %@NL@%
  5091. You must always supply NMAKE with a description file. In addition to
  5092. description blocks, which tell NMAKE how to build your project's target
  5093. files, the description file can contain comments, macros, inference rules,
  5094. and directives. This section describes all the elements of description
  5095. files.  %@NL@%
  5096. %@NL@%
  5097. %@NL@%
  5098. %@3@%%@CR:C6A00060005 @%%@AB@%6.3.1  Description Blocks%@AE@%%@EH@%%@NL@%
  5099. %@NL@%
  5100. Description blocks form the heart of the description file. Figure 6.1
  5101. illustrates a typical NMAKE description block, including the three parts:
  5102. targets, dependents, and commands.  %@NL@%
  5103. %@NL@%
  5104. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  5105. %@NL@%
  5106. %@AU@% A target is a file that you want to build.%@AE@%  %@NL@%
  5107. %@NL@%
  5108. The targets part of the description block lists one or more files to build.
  5109. The line that lists targets and dependents is called the "dependency line."
  5110. %@NL@%
  5111. %@NL@%
  5112. The example in Figure 6.1 tells NMAKE to build a single target, MYAPP.EXE.
  5113. Although single targets are common, you can also list multiple targets;
  5114. separate each target name with a space. If the rightmost target name is one
  5115. character long, put a space between the name and the colon.  %@NL@%
  5116. %@NL@%
  5117. The target is normally a file, but it can also be a "pseudotarget," a name
  5118. that allows you to build groups of files or execute a group of commands. See
  5119. Section 6.3.6, "Pseudotargets."  %@NL@%
  5120. %@NL@%
  5121. %@AU@% A dependent is a file used to build a target.%@AE@%  %@NL@%
  5122. %@NL@%
  5123. The dependents part of the description block lists one or more files from
  5124. which the target is built. It is separated from the targets part by a colon.
  5125. The example in Figure 6.1 lists three dependents:  %@NL@%
  5126. %@NL@%
  5127. %@AS@%  myapp.exe : myapp.obj another.obj myapp.def%@AE@%%@NL@%
  5128. %@NL@%
  5129. The example tells NMAKE to build the target MYAPP.EXE whenever MYAPP.OBJ,
  5130. ANOTHER.OBJ, or MYAPP.DEF has changed more recently than MYAPP.EXE.  %@NL@%
  5131. %@NL@%
  5132. If any dependents of a target are listed as targets in other description
  5133. blocks, then NMAKE builds those files before it builds the original target.
  5134. Essentially NMAKE evaluates a "dependency tree" for the entire description
  5135. file. It builds files in the order needed to update the original target,
  5136. never building a target until all files that depend on it are up-to-date.  %@NL@%
  5137. %@NL@%
  5138. The dependent list can also include a list of directories in which NMAKE
  5139. should search for dependents. The directory list is enclosed in curly braces
  5140. ( {} ) and precedes the dependent list. NMAKE searches the current directory
  5141. first, then the directories you list:  %@NL@%
  5142. %@NL@%
  5143. %@AS@%  forward.exe : {\src\alpha;d:\proj}pass.obj%@AE@%%@NL@%
  5144. %@NL@%
  5145. In the line above, the target, FORWARD.EXE, has one dependent: PASS.OBJ. The
  5146. directory list specifies two directories:  %@NL@%
  5147. %@NL@%
  5148. %@AS@%  {\src\alpha;d:\proj}%@AE@%%@NL@%
  5149. %@NL@%
  5150. NMAKE begins searching for PASS.OBJ in the current directory. If it is not
  5151. found, NMAKE searches the \ SRC \ ALPHA directory, then the D:\ PROJ
  5152. directory. If NMAKE cannot find a dependent in the current directory or a
  5153. listed directory, it looks for an inference rule that describes how to
  5154. create the dependent (see Section 6.3.4, "Inference Rules").  %@NL@%
  5155. %@NL@%
  5156. %@AU@% The commands part of a  description block can contain  one or more
  5157. %@AU@%commands.%@AE@%  %@NL@%
  5158. %@NL@%
  5159. The commands part of the description block lists the command(s) NMAKE should
  5160. use to build the target. This can be any command that you can execute from
  5161. the command line. The example tells NMAKE to build MYAPP.EXE using the
  5162. following LINK command:  %@NL@%
  5163. %@NL@%
  5164. %@AS@%    LINK myapp another.obj, /align:16, NUL, os2, myapp%@AE@%%@NL@%
  5165. %@NL@%
  5166. Notice that the line above is indented. NMAKE uses indentation to
  5167. distinguish between the dependency line and command line. If the command
  5168. appears on a separate line, as here, it must be indented at least one space
  5169. or tab. The dependency line must not be indented (it cannot start with a
  5170. space or tab).  %@NL@%
  5171. %@NL@%
  5172. Many targets are built with a single command, but you can place more than
  5173. one command after the dependency line. A long command can span several lines
  5174. if each line ends with a backslash ( \ ).  %@NL@%
  5175. %@NL@%
  5176. You can also place the command at the end of the dependency line. Separate
  5177. the command from the rightmost dependent with a semicolon.  %@NL@%
  5178. %@NL@%
  5179. In OS/2 description files, NMAKE imposes a slight restriction on the use of
  5180. the CD, CHDIR, and SET commands. Do not place any of these commands on a
  5181. command line that uses the ampersand (&) to execute multiple commands. For
  5182. instance, the following command line is legal in an OS/2 description file,  %@NL@%
  5183. %@NL@%
  5184. %@AS@%  DIR & COPY sample.c backup.c%@AE@%%@NL@%
  5185. %@NL@%
  5186. but this line is not legal because it places a CD command after the
  5187. ampersand:  %@NL@%
  5188. %@NL@%
  5189. %@AS@%  DIR & CD \mydir%@AE@%%@NL@%
  5190. %@NL@%
  5191. To use CD, CHDIR, or SET in a description block, place the command on a
  5192. separate line:  %@NL@%
  5193. %@NL@%
  5194. %@AS@%  DIR
  5195. %@AS@%  CD \mydir%@AE@%%@NL@%
  5196. %@NL@%
  5197. Your OS/2 user's documentation contains more information about using the
  5198. ampersand in command lines.  %@NL@%
  5199. %@NL@%
  5200. %@NL@%
  5201. %@4@%%@AB@%Wild Cards%@AE@%%@EH@%%@NL@%
  5202. %@NL@%
  5203. You can use DOS wild-card characters (* and ?) to specify target and
  5204. dependent file names. NMAKE expands wild cards in target names when it reads
  5205. the description file. It expands wild cards in the dependent names when it
  5206. builds the target. For example, the following description block compiles all
  5207. source files with the .C extension:  %@NL@%
  5208. %@NL@%
  5209. %@AS@%  bondo.exe : *.c
  5210. %@AS@%      CL *.c%@AE@%%@NL@%
  5211. %@NL@%
  5212. %@NL@%
  5213. %@4@%%@AB@%Command Modifiers%@AE@%%@EH@%%@NL@%
  5214. %@NL@%
  5215. Command modifiers provide extra control over the command listed in a
  5216. description block. They are special characters that appear in front of a
  5217. command. You can use more than one modifier for a single command. Table 6.1
  5218. describes the three NMAKE command modifiers.  %@NL@%
  5219. %@NL@%
  5220. %@AB@%Table   %@AB@%6.1 Command Modifiers%@AE@%%@AE@%
  5221.  
  5222. %@TH:  45  2536 02 34 42 @%
  5223. Character                         Action
  5224. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5225. At sign (@)                       Prevents NMAKE from displaying the 
  5226.                                   command as it executes. In the example 
  5227.                                   below, NMAKE does not display the ECHO 
  5228.                                   command line:
  5229.  
  5230.                                   %@AS@%sort.exe : sort.obj%@AE@%
  5231.                                   %@AS@%   @ECHO sorting%@AE@%
  5232.  
  5233.                                   The output of the ECHO command appears 
  5234.                                   as usual.
  5235.  
  5236. Dash (-)                          Turns off error checking for the command.
  5237.                                   If the dash is followed by a number, 
  5238.                                   NMAKE stops only if the error level 
  5239.                                   returned by the command is greater than 
  5240.                                   the number. In the following example, if
  5241.                                   the program %@AS@% sample %@AE@% returned an error 
  5242.                                   code NMAKE does not stop but continues 
  5243.                                   to execute commands:
  5244.  
  5245.                                   %@AS@%light.lst : light.txt%@AE@%
  5246.                                   %@AS@%   -sample light.txt%@AE@%
  5247.  
  5248. Exclamation point (!)             Executes the command for each dependent 
  5249.                                   file if the command uses the predefined 
  5250.                                   macros %@AB@%$?%@AE@% or %@AB@%$**%@AE@%. The %@AB@%$?%@AE@% macro refers to
  5251.                                   all dependent files that are out-of-date
  5252.                                   with respect to the target. The %@AB@%$**%@AE@% 
  5253.                                   macro refers to all dependent files in 
  5254.                                   the description block (see Section 6.3.3,
  5255.                                   "Macros"). For example,
  5256.  
  5257.                                   %@AS@%print:hop.asm skip.bas jump.c%@AE@%
  5258.                                   %@AS@%   !print $** lpt1:%@AE@%
  5259.  
  5260.                                   generates the following commands:
  5261.  
  5262.                                   %@AS@%print hop.asm lpt1:%@AE@%
  5263.                                   %@AS@%print skip.bas lpt1:%@AE@%
  5264.                                   %@AS@%print jump.c lpt1:%@AE@%
  5265.  
  5266. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5267.  
  5268. %@TE:  45  2536 02 34 42 @%
  5269.  
  5270. %@NL@%
  5271. %@4@%%@AB@%Using Control Characters as Literals%@AE@%%@EH@%%@NL@%
  5272. %@NL@%
  5273. Occasionally, you may need to list a file name that contains a character
  5274. that NMAKE uses as a control character. These characters are  %@NL@%
  5275. %@NL@%
  5276. # ( ) $ ^ \ { } ! @ -  %@NL@%
  5277. %@NL@%
  5278. To use an NMAKE control character as a literal character, place a caret (^)
  5279. in front of it. For example, say that you define a macro that ends with a
  5280. backslash:  %@NL@%
  5281. %@NL@%
  5282. %@AS@%  exepath=c:\bin\%@AE@%%@NL@%
  5283. %@NL@%
  5284. The line above is intended to define a macro named %@AS@% exepath %@AE@% with the value %@AS@%
  5285. %@AS@%c:\bin\%@AE@%. But the second backslash causes unexpected results. Since the
  5286. back-slash is the NMAKE line-continuation character, the line actually
  5287. defines the macro %@AS@% exepath %@AE@% as %@AS@% c:\bin %@AE@% followed by whatever appears on the
  5288. next line of the description file. You can solve the problem by placing a
  5289. caret in front of the second backslash:  %@NL@%
  5290. %@NL@%
  5291. %@AS@%  exepath=c:\bin^\%@AE@%%@NL@%
  5292. %@NL@%
  5293. You can also use a caret to place a literal newline character in a
  5294. description file. This feature can be useful in macro definitions:  %@NL@%
  5295. %@NL@%
  5296. %@AS@%  XYZ=abc^
  5297. %@AS@%  def%@AE@%%@NL@%
  5298. %@NL@%
  5299. NMAKE interprets the example as if you assigned the C-style string %@AS@% abc\ndef
  5300. %@AS@%%@AE@%to the %@AS@% XYZ %@AE@% macro. This effect differs from using the backslash ( \s ) to
  5301. continue a line. A newline character that follows a backslash is replaced
  5302. with a space.  %@NL@%
  5303. %@NL@%
  5304. Carets that precede noncontrol characters are ignored. The line  %@NL@%
  5305. %@NL@%
  5306. %@AS@%  ign^ore : these ca^rets%@AE@%%@NL@%
  5307. %@NL@%
  5308. is interpreted as  %@NL@%
  5309. %@NL@%
  5310. %@AS@%  ignore : these carets%@AE@%%@NL@%
  5311. %@NL@%
  5312. A caret that appears in quotation marks is treated as a literal caret
  5313. character.  %@NL@%
  5314. %@NL@%
  5315. %@NL@%
  5316. %@4@%%@AB@%Listing a Target in Multiple Description Blocks%@AE@%%@EH@%%@NL@%
  5317. %@NL@%
  5318. You can specify more than one description block for the same target by
  5319. placing two colons (::) after the target. This feature can be useful for
  5320. building a complex target, such as a library, that contains components
  5321. created with different commands. For example,  %@NL@%
  5322. %@NL@%
  5323. %@AS@%  target.lib :: a.asm b.asm c.asm
  5324. %@AS@%     CL a.asm b.asm c.asm
  5325. %@AS@%     LIB target -+a.obj -+b.obj -+c.obj; 
  5326. %@AS@%  target.lib :: d.c e.c
  5327. %@AS@%     CL /c d.c e.c
  5328. %@AS@%     LIB target -+d.obj -+e.obj;%@AE@%%@NL@%
  5329. %@NL@%
  5330. Both description blocks update the library named TARGET.LIB. If any of the
  5331. assembly-language files have changed more recently than the library, NMAKE
  5332. executes the commands in the first block to assemble the source files and
  5333. update  %@NL@%
  5334. %@NL@%
  5335. the library. Similarly, if any of the C-language files have changed, NMAKE
  5336. executes the second group of commands, which compile the C files and update
  5337. the library.  %@NL@%
  5338. %@NL@%
  5339. If you use a single colon in the example above, NMAKE issues an error
  5340. message. It is legal, however, to use single colons if commands are listed
  5341. in only one block. In this case, dependency lines are cumulative. For
  5342. example,  %@NL@%
  5343. %@NL@%
  5344. %@AS@%  target: jump.bas
  5345. %@AS@%  target: up.c
  5346. %@AS@%     echo Building target...%@AE@%%@NL@%
  5347. %@NL@%
  5348. is equivalent to  %@NL@%
  5349. %@NL@%
  5350. %@AS@%  target: jump.bas up.c
  5351. %@AS@%     echo Building target...%@AE@%%@NL@%
  5352. %@NL@%
  5353. %@NL@%
  5354. %@3@%%@CR:C6A00060006 @%%@AB@%6.3.2  Comments%@AE@%%@EH@%%@NL@%
  5355. %@NL@%
  5356. You can place comments in a description file by preceding them with a number
  5357. sign (#):  %@NL@%
  5358. %@NL@%
  5359. %@AS@%  # This comment appears on its own line
  5360. %@AS@%  huey.exe : huey.obj dewey.obj # Comment on the same line
  5361. %@AS@%     link huey.obj dewey.obj;%@AE@%%@NL@%
  5362. %@NL@%
  5363. A comment extends to the end of the line in which it appears. Command lines
  5364. cannot contain comments.  %@NL@%
  5365. %@NL@%
  5366. %@NL@%
  5367. %@3@%%@CR:C6A00060007 @%%@AB@%6.3.3  Macros%@AE@%%@EH@%%@NL@%
  5368. %@NL@%
  5369. %@AU@% Macros allow you to do text replacements throughout the description file.%@AE@%  %@NL@%
  5370. %@NL@%
  5371. Macros offer a convenient way to replace a string in the description file
  5372. with another string. The text is automatically replaced each time you run
  5373. NMAKE. Macros are useful in a variety of tasks, including the following:  %@NL@%
  5374. %@NL@%
  5375. %@NL@%
  5376.   ■   To create a standard description file for several projects. The macro
  5377.       represents the file names used in commands. These file names are then
  5378.       defined when you run NMAKE. When you switch to a different project,
  5379.       you can change file names throughout the description file by changing
  5380.       a single macro.%@NL@%
  5381. %@NL@%
  5382.   ■   To control the options that NMAKE passes to the compiler or linker.
  5383.       When you specify options in a macro, you can change options throughout
  5384.       the description file in one easy step.%@NL@%
  5385. %@NL@%
  5386. %@NL@%
  5387. You can define your own macros or use predefined macros. This section begins
  5388. by describing user-defined macros.  %@NL@%
  5389. %@NL@%
  5390. %@NL@%
  5391. %@4@%%@AB@%User-Defined Macros%@AE@%%@EH@%%@NL@%
  5392. %@NL@%
  5393. You can define a macro with  %@NL@%
  5394. %@NL@%
  5395. %@AS@%  macroname = string%@AE@%%@NL@%
  5396. %@NL@%
  5397. The %@AI@%macroname%@AE@% can be any combination of letters, digits, and the underscore
  5398. ( _ ) character. Macro names are case sensitive. NMAKE interprets %@AS@% MyMacro %@AE@%
  5399. and %@AS@% MYMACRO %@AE@% as different macro names.  %@NL@%
  5400. %@NL@%
  5401. The %@AI@%string%@AE@% can be any string, including a null string. For example,  %@NL@%
  5402. %@NL@%
  5403. %@AS@%  command = LINK%@AE@%%@NL@%
  5404. %@NL@%
  5405. defines a macro named %@AS@% command %@AE@% and assigns it the string %@AS@% LINK%@AE@%.  %@NL@%
  5406. %@NL@%
  5407. You can define macros in the description file or on the command line. In the
  5408. description file, you must define each macro on a separate line; the line
  5409. cannot start with a space or tab. The %@AI@%string%@AE@% can contain embedded spaces,
  5410. and NMAKE ignores spaces on either side of the equal sign. You do not need
  5411. to enclose %@AI@%string%@AE@% in quotation marks (if you do, they become part of the
  5412. string).  %@NL@%
  5413. %@NL@%
  5414. Slightly different rules apply when you define a macro on the command line,
  5415. because of the way that the command line handles spaces. You must enclose
  5416. %@AI@%string%@AE@% in quotation marks if it contains embedded spaces. No spaces can
  5417. surround the equal sign. You can also enclose the entire macro definition,
  5418. %@AI@%macroname%@AE@% and %@AI@%string%@AE@%, in quotation marks. For example,  %@NL@%
  5419. %@NL@%
  5420. %@AS@%  NMAKE "program=sample"%@AE@%%@NL@%
  5421. %@NL@%
  5422. defines the macro %@AS@% program%@AE@%, assigning it the value %@AS@% sample%@AE@%.  %@NL@%
  5423. %@NL@%
  5424. Once you have defined a macro, you can "undefine" it with the !UNDEF
  5425. directive (see Section 6.3.5, "Directives").  %@NL@%
  5426. %@NL@%
  5427. %@NL@%
  5428. %@4@%%@AB@%Invoking Macros%@AE@%%@EH@%%@NL@%
  5429. %@NL@%
  5430. You invoke a macro by enclosing its name in parentheses preceded by a dollar
  5431. sign ($). (The parentheses are optional if %@AI@%macroname%@AE@% is one character long.)
  5432. For example, you can invoke the %@AS@% command %@AE@% macro defined above as  %@NL@%
  5433. %@NL@%
  5434. %@AS@%  $(command)%@AE@%%@NL@%
  5435. %@NL@%
  5436. When NMAKE runs, it replaces every occurrence of %@AS@% $(command) %@AE@% with %@AS@% LINK%@AE@%.
  5437. The following description file defines and uses three macros:  %@NL@%
  5438. %@NL@%
  5439. %@AS@%  program = sample
  5440. %@AS@%  c = LINK
  5441. %@AS@%  options = 
  5442. %@AS@%  
  5443. %@AS@%  $(program).exe : $(program).obj
  5444. %@AS@%     $c  $(options)  $(program).obj;%@AE@%%@NL@%
  5445. %@NL@%
  5446. NMAKE interprets the description block as  %@NL@%
  5447. %@NL@%
  5448. %@AS@%  sample.exe : sample.obj
  5449. %@AS@%     LINK    sample.obj;%@AE@%%@NL@%
  5450. %@NL@%
  5451. NMAKE replaces every occurrence of %@AS@% $(program) %@AE@% with %@AS@% sample%@AE@%, every instance
  5452. of %@AS@% $c %@AE@% with %@AS@% LINK%@AE@%, and every instance of %@AS@% $(options) %@AE@%with a null string.
  5453. Because %@AS@% c %@AE@% is only one character long, you do not need to enclose it in
  5454. parentheses.  %@NL@%
  5455. %@NL@%
  5456. If you invoke a macro that is not defined, NMAKE treats the macro as a null
  5457. string.  %@NL@%
  5458. %@NL@%
  5459. Occasionally, you may need to use the dollar sign ($) as a literal
  5460. character. Use two signs ($$), or precede it with a caret (^$).  %@NL@%
  5461. %@NL@%
  5462. %@NL@%
  5463. %@4@%%@AB@%Predefined Macros%@AE@%%@EH@%%@NL@%
  5464. %@NL@%
  5465. NMAKE provides several predefined macros, which represent various file names
  5466. and commands. Predefined macros are useful in their own right, and they are
  5467. also employed in predefined inference rules, which are described later in
  5468. this chapter. Table 6.2 lists NMAKE predefined macros.  %@NL@%
  5469. %@NL@%
  5470. %@AB@%Table   %@AB@%6.2  Predefined Macros%@AE@%%@AE@%
  5471.  
  5472. %@TH:  29  1603 02 34 42 @%
  5473. Macro                             Meaning
  5474. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5475. %@AB@%$@ %@AE@%                               The current target's full name.
  5476.  
  5477. %@AB@%$* %@AE@%                               The current target's base name (full 
  5478.                                   name minus the file 
  5479.                                   extension).
  5480.  
  5481. %@AB@%$** %@AE@%                              The dependents of the current target.
  5482.  
  5483. %@AB@%$? %@AE@%                               The dependents that are out-of-date with
  5484.                                   respect to the current target.
  5485.  
  5486. %@AB@%$$@ %@AE@%                              The target that NMAKE is currently 
  5487.                                   evaluating. You can only use this macro 
  5488.                                   to specify a dependent.
  5489.  
  5490. %@AB@%$< %@AE@%                               The dependent file that is out-of-date 
  5491.                                   with respect to the current target 
  5492.                                   (evaluated only for inference rules).
  5493.  
  5494. %@AB@%$(CC) %@AE@%                            The command to invoke the C compiler. By
  5495.                                   default,%@AB@% $(CC)%@AE@% is predefined as %@AS@% CC = cl%@AE@%,
  5496.                                   which invokes the optimizing compiler.
  5497.  
  5498. %@AB@%$(AS)  %@AE@%                           The command that invokes the Microsoft 
  5499.                                   Macro Assembler. NMAKE predefines this 
  5500.                                   macro as %@AS@% AS = masm%@AE@%. 
  5501.  
  5502. %@TE:  29  1603 02 34 42 @%
  5503.  
  5504. %@AB@%Table   %@AB@%6.2  (continued)%@AE@%%@AE@%
  5505.  
  5506. %@TH:  53  3240 02 34 42 @%
  5507. Macro                             Meaning
  5508. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5509. %@AB@%$(MAKE)  %@AE@%                         The name with which the NMAKE utility is
  5510.                                   invoked. This macro is used to invoke 
  5511.                                   NMAKE recursively. It causes the line on
  5512.                                   which it appears to be executed even if 
  5513.                                   the /N option is on. You can redefine 
  5514.                                   this macro if you want to execute 
  5515.                                   another program. 
  5516.                                   The %@AB@%$(MAKE)%@AE@% macro is useful for building
  5517.                                   different versions of a program. The 
  5518.                                   following description file invokes NMAKE
  5519.                                   recursively to build targets in the 
  5520.                                   VERS1 and VERS2 directories.
  5521.  
  5522.                                   %@AS@%all :vers1 vers2%@AE@%
  5523.                                   %@AS@%versl  :%@AE@%
  5524.                                   %@AS@%   cd versl%@AE@%
  5525.                                   %@AS@%   $(MAKE)%@AE@%
  5526.                                   %@AS@%   cd  . .%@AE@%
  5527.                                   %@AS@%vers2 :%@AE@%
  5528.                                   %@AS@%   cd vers2%@AE@%
  5529.                                   %@AS@%   $(MAKE)%@AE@%
  5530.                                   %@AS@%   cd . .%@AE@%
  5531.  
  5532.                                   The example changes to the VERS1 
  5533.                                   directory, then invokes NMAKE 
  5534.                                   recursively, causing NMAKE to process 
  5535.                                   the file MAKEFILE in that directory. 
  5536.                                   Then it changes to the VERS2 directory 
  5537.                                   and invokes NMAKE again, processing the 
  5538.                                   file MAKEFILE in that directory.
  5539.                                   Deeply recursive build procedures can 
  5540.                                   exhaust NMAKE's run-time stack, causing 
  5541.                                   a run-time error. To eliminate the error,
  5542.                                   use the EXEHDR utility to increase 
  5543.                                   NMAKE's run-time stack. The following 
  5544.                                   command, for example, gives NMAKE.EXE a 
  5545.                                   stack size of 16,384 (0x4000) bytes:
  5546.  
  5547.                                   %@AS@%exehdr /stack:0x4000 nmake.exe%@AE@%
  5548.  
  5549. %@AB@%$(MAKEFLAGS) %@AE@%                     The NMAKE options currently in effect. 
  5550.                                   If you invoke NMAKE recursively, you 
  5551.                                   should use the command: %@AS@% $(MAKE)%@AE@% %@AS@% %@AE@%
  5552.                                   %@AS@%$(MAKEFLAGS)%@AE@%. You cannot redefine this 
  5553.                                   macro.
  5554.  
  5555. %@AB@%$(MAKEDIR) %@AE@%                       The directory from which NMAKE is 
  5556.                                   invoked.
  5557.  
  5558. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5559.  
  5560. %@TE:  53  3240 02 34 42 @%
  5561.  
  5562. Like user-defined macro names, predefined macro names are case sensitive.
  5563. NMAKE interprets %@AS@% CC %@AE@% and %@AS@% cc %@AE@% as different macro names.  %@NL@%
  5564. %@NL@%
  5565. %@AU@% Macro modifiers allow you to specify parts of predefined macros
  5566. %@AU@%representing file names.%@AE@%  %@NL@%
  5567. %@NL@%
  5568. You can append characters to any of the first six macros in Table 6.2 to
  5569. modify its meaning. Appending a %@AB@%D%@AE@% specifies the directory part of the file
  5570. name only, an %@AB@%F%@AE@% specifies the file name, a %@AB@%B%@AE@% specifies just the base name,
  5571. and an %@AB@%R%@AE@% specifies the complete file name without the extension. If you add
  5572. one of these characters, you must enclose the macro name in parentheses.
  5573. (The predefined macros %@AB@%$$@%@AE@% and %@AB@%$**%@AE@% are the only exceptions to the rule that
  5574. macro names more than one character long must be enclosed in parentheses.)  %@NL@%
  5575. %@NL@%
  5576. For example, assume that %@AB@%$@%@AE@% has the value C:\ SOURCE \ PROG \ SORT.OBJ. The
  5577. list below shows the effect of combining the special characters with %@AB@%$@%@AE@%:  %@NL@%
  5578. %@NL@%
  5579. %@AB@%Macro%@AE@%                             %@AB@%Value%@AE@%
  5580. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5581. %@AB@%$(@D)%@AE@%                             C:\ SOURCE \ PROG
  5582.  
  5583. %@AB@%$(@F)%@AE@%                             SORT.OBJ
  5584.  
  5585. %@AB@%$(@B)%@AE@%                             SORT
  5586.  
  5587. %@AB@%$(@R)%@AE@%                             C:\ SOURCE \ PROG \ SORT
  5588.  
  5589. For example, in the code below, the macro %@AB@%$?%@AE@% represents the names of all
  5590. dependents that are more recent than the target. The exclamation point
  5591. causes NMAKE to execute the LIB command once for each dependent in the list.
  5592. As a result, the LIB command is executed up to three times, each time
  5593. replacing a module with a newer version.  %@NL@%
  5594. %@NL@%
  5595. %@AS@%  trig.lib : sin.obj cos.obj arctan.obj
  5596. %@AS@%          !LIB trig.lib -+$?;%@AE@%%@NL@%
  5597. %@NL@%
  5598. In the following example, NMAKE updates a group of include files:  %@NL@%
  5599. %@NL@%
  5600. %@AS@%  # Include files depend on versions in current directory
  5601. %@AS@%  DIR=c:\include
  5602. %@AS@%  $(DIR)\globals.h : globals.h
  5603. %@AS@%   COPY globals.h $@
  5604. %@AS@%  $(DIR)\types.h : types.h
  5605. %@AS@%   COPY types.h $@
  5606. %@AS@%  $(DIR)\macros.h : macros.h
  5607. %@AS@%   COPY macros.h $@%@AE@%%@NL@%
  5608. %@NL@%
  5609. Each of the files GLOBALS.H, TYPES.H, and MACROS.H in the directory  C:\
  5610. INCLUDE depends on its counterpart in the current directory. If one of the
  5611. include files is out-of-date, NMAKE replaces it with the file of the same
  5612. name from the current directory.  %@NL@%
  5613. %@NL@%
  5614. %@NL@%
  5615. %@4@%%@AB@%Substitution within Macros%@AE@%%@EH@%%@NL@%
  5616. %@NL@%
  5617. Just as macros allow you to substitute text in a description file, you can
  5618. also substitute text within a macro itself. Use the following form:  %@NL@%
  5619. %@NL@%
  5620. %@AS@%  $(macroname:string1 = string2)%@AE@%%@NL@%
  5621. %@NL@%
  5622. %@AU@% You can replace text in a macro, as well as in the description file.%@AE@%  %@NL@%
  5623. %@NL@%
  5624. Every occurrence of %@AI@%string1%@AE@% is replaced by %@AI@%string2%@AE@% in the macro %@AI@%macroname%@AE@%.
  5625. Do not put any spaces or tabs between %@AI@%macroname%@AE@% and the colon. Spaces
  5626. between the colon and %@AI@%string1%@AE@% are made part of %@AI@%string1%@AE@%. If %@AI@%string2%@AE@% is a null
  5627. string, all occurrences of %@AI@%string1%@AE@% are deleted from the %@AI@%macroname%@AE@% macro.  %@NL@%
  5628. %@NL@%
  5629. The following description file illustrates macro substitution:  %@NL@%
  5630. %@NL@%
  5631. %@AS@%  SRCS = prog.c sub1.c sub2.c 
  5632. %@AS@%  prog.exe : $(SRCS:.c=.obj)
  5633. %@AS@%          LINK  $**;
  5634. %@AS@%  
  5635. %@AS@%  DUP : $(SRCS)
  5636. %@AS@%          !COPY $** c:\backup%@AE@%%@NL@%
  5637. %@NL@%
  5638. The predefined macro %@AB@%$**%@AE@% stands for the names of all the dependent files
  5639. (see the previous section). If you invoke the example file with a command
  5640. line that specifies both targets, NMAKE executes the following commands:  %@NL@%
  5641. %@NL@%
  5642. %@AS@%  LINK prog.obj sub1.obj sub2.obj;%@AE@%%@NL@%
  5643. %@NL@%
  5644. %@AS@%  COPY prog.c c:\backup
  5645. %@AS@%  COPY sub1.c c:\backup
  5646. %@AS@%  COPY sub2.c c:\backup%@AE@%%@NL@%
  5647. %@NL@%
  5648. The macro substitution does not alter the definition of the %@AS@% SRCS %@AE@% macro,
  5649. rather, it simply replaces the listed characters. When NMAKE builds the
  5650. target PROG.EXE, it gets the definition for the predefined macro %@AB@%$**%@AE@% (the
  5651. dependent list) from the dependency line, which specifies the macro
  5652. substitution in %@AS@% SRCS%@AE@%. The same is true for the second target, %@AS@% DUP%@AE@%. In this
  5653. case, however, no macro substitution is requested, so %@AS@% SRCS %@AE@% retains its
  5654. original value, and %@AB@%$**%@AE@% represents the names of the C source files. (In the
  5655. example above, the target %@AS@% DUP %@AE@% is a pseudotarget; Section 6.3.6 describes
  5656. pseudotargets.)  %@NL@%
  5657. %@NL@%
  5658. You can also perform substitution in the following predefined macros: %@AB@%$@%@AE@%,
  5659. %@AB@%$*%@AE@%, %@AB@%$**%@AE@%, %@AB@%$?%@AE@%, and%@AB@% $%@AE@%. The principle is the same as for other macros. The
  5660. command in the following description block substitutes within a predefined
  5661. macro:  %@NL@%
  5662. %@NL@%
  5663. %@AS@%  target.abc : depend.xyz
  5664. %@AS@%     echo $(@:targ=blank)%@AE@%%@NL@%
  5665. %@NL@%
  5666. If dependent %@AS@% depend.xyz %@AE@% is out-of-date relative to target %@AS@% target.abc%@AE@%,
  5667. then NMAKE executes the command  %@NL@%
  5668. %@NL@%
  5669. %@AS@%  echo blanket.abc%@AE@%%@NL@%
  5670. %@NL@%
  5671. The example uses the predefined macro %@AB@%$@%@AE@%, which equals the full name of the
  5672. current target ( %@AS@%target.abc%@AE@%). It substitutes %@AS@% blank %@AE@% for %@AS@% targ %@AE@% in the
  5673. target, resulting in %@AS@% blanket.abc%@AE@%. Note that you do not put the usual dollar
  5674. sign in front of the predefined macro. The example uses  %@NL@%
  5675. %@NL@%
  5676. %@AS@%  $(@:targ=blank)%@AE@%%@NL@%
  5677. %@NL@%
  5678. instead of  %@NL@%
  5679. %@NL@%
  5680. %@AS@%  $($@:targ=blank)%@AE@%%@NL@%
  5681. %@NL@%
  5682. to substitute within the predefined macro %@AB@%$@%@AE@%.  %@NL@%
  5683. %@NL@%
  5684. %@NL@%
  5685. %@4@%%@AB@%Inherited Macros%@AE@%%@EH@%%@NL@%
  5686. %@NL@%
  5687. When NMAKE executes, it creates macros equivalent to every current
  5688. environment variable. These are called "inherited" macros because they have
  5689. the same names and values as the corresponding environment%@CR:C6A00060008 @% variables. (The
  5690. inherited macro is all uppercase, however, even if the corresponding
  5691. environment variable is not.)  %@NL@%
  5692. %@NL@%
  5693. Inherited macros can be used like other macros. You can also redefine them.
  5694. The following example redefines the inherited macro %@AS@% PATH%@AE@%:  %@NL@%
  5695. %@NL@%
  5696. %@AS@%  PATH = c:\tools\bin
  5697. %@AS@%  
  5698. %@AS@%  sample.obj : sample.c
  5699. %@AS@%     CL /c sample.c%@AE@%%@NL@%
  5700. %@NL@%
  5701. %@AU@% Inherited macros take their definitions from environment variables.%@AE@%  %@NL@%
  5702. %@NL@%
  5703. No matter what value PATH had in the DOS environment, it has the value %@AS@%
  5704. %@AS@%c:\tools\bin %@AE@% when NMAKE executes the CL command in this description block.
  5705. Redefining the inherited macro does not affect the original environment
  5706. variable; when NMAKE terminates, PATH has its original value.  %@NL@%
  5707. %@NL@%
  5708. The /E option defeats macro inheritance. If you supply this option, NMAKE
  5709. ignores any attempt to redefine a macro that derives from an environment
  5710. variable.  %@NL@%
  5711. %@NL@%
  5712. %@NL@%
  5713. %@4@%%@AB@%Precedence among Macro Definitions%@AE@%%@EH@%%@NL@%
  5714. %@NL@%
  5715. If you define the same macro in more than one place, NMAKE uses the macro
  5716. with the highest precedence. The precedence from highest to lowest is as
  5717. follows:  %@NL@%
  5718. %@NL@%
  5719. %@NL@%
  5720.   1.  Macros defined on the command line%@NL@%
  5721. %@NL@%
  5722.   2.  Macros defined in a description file or include file%@NL@%
  5723. %@NL@%
  5724.   3.  Inherited macros%@NL@%
  5725. %@NL@%
  5726.   4.  Macros defined in the TOOLS.INI file%@NL@%
  5727. %@NL@%
  5728.   5.  Predefined macros such as%@AB@% CC %@AE@%and%@AB@% AS%@AE@%%@NL@%
  5729. %@NL@%
  5730. %@NL@%
  5731. The /E option defeats any attempt to redefine inherited macros. If you run
  5732. NMAKE with this option, macros inherited from environment variables override
  5733. any same-named macros in the description file.  %@NL@%
  5734. %@NL@%
  5735. %@NL@%
  5736. %@3@%%@CR:C6A00060009 @%%@AB@%6.3.4  Inference Rules%@AE@%%@EH@%%@NL@%
  5737. %@NL@%
  5738. Inference rules are templates that NMAKE uses to create files with a given
  5739. extension. For instance, when NMAKE encounters a description block with no
  5740. commands, it tries to apply an inference rule that tells how to create the
  5741. target from the dependent files, given the two extensions. Similarly, if a
  5742. dependent file does not exist, NMAKE tries to apply an inference rule that
  5743. tells how to create the missing dependent from another file with the same
  5744. base name.  %@NL@%
  5745. %@NL@%
  5746. %@AU@% Inference rules tell NMAKE how to create files with a certain extension.%@AE@%  %@NL@%
  5747. %@NL@%
  5748. Inference rules provide a convenient shorthand for common operations. For
  5749. instance, you can use an inference rule to avoid repeating the same command
  5750. in several description blocks.  %@NL@%
  5751. %@NL@%
  5752. You can define your own inference rules or use predefined inference rules.
  5753. This section begins by describing user-defined inference rules.  %@NL@%
  5754. %@NL@%
  5755. %@NL@%
  5756. %@4@%%@AB@%User-Defined Inference Rules%@AE@%%@EH@%%@NL@%
  5757. %@NL@%
  5758. You can define inference rules in the description file or in the TOOLS.INI
  5759. file. An inference-rule definition lists two file extensions and one or more
  5760. commands. For instance, the following inference rule tells NMAKE how to
  5761. build a .OBJ file using a .C file:%@CR:C6A00060010 @%  %@NL@%
  5762. %@NL@%
  5763. %@AS@%  .C.OBJ:
  5764. %@AS@%     CL /c $<;%@AE@%%@NL@%
  5765. %@NL@%
  5766. The first line lists two extensions. The second extension (.OBJ) specifies
  5767. the type of the desired file and the first (.C) specifies the type of the
  5768. desired file's dependent. The second line lists the command used to build
  5769. the desired file. Here, the predefined macro %@AB@%$%@AE@% represents the name of a
  5770. dependent that is out-of-date relative to the target.  %@NL@%
  5771. %@NL@%
  5772. NMAKE could apply the above inference rule to the following description
  5773. block:  %@NL@%
  5774. %@NL@%
  5775. %@AS@%  sample.obj :%@AE@%%@NL@%
  5776. %@NL@%
  5777. The description block lists only a target, SAMPLE.OBJ. Both the dependent
  5778. and the command are missing. However, given the target's base name and
  5779. extension, plus the above inference rule, NMAKE has enough information to
  5780. build the target. NMAKE first looks for a .C file with the same base name as
  5781. the target. If SAMPLE.C exists, NMAKE compares its date to that of
  5782. SAMPLE.OBJ (the comparison is triggered by the predefined macro %@AB@%$%@AE@%). If
  5783. SAMPLE.C has changed more recently, NMAKE compiles it using the CL command
  5784. listed in the inference rule:  %@NL@%
  5785. %@NL@%
  5786. %@AS@%  CL/c sample.c%@AE@%%@NL@%
  5787. %@NL@%
  5788. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5789. NOTE
  5790.  
  5791. %@AI@%NMAKE applies an inference rule only if the base name of the file it is
  5792. %@AI@%trying to create matches the base name of a file that already exists. Thus,
  5793. %@AI@%inference rules are useful only when there is a one-to-one correspondence
  5794. %@AI@%between the desired file and its dependent. You cannot define an inference
  5795. %@AI@%rule that replaces several modules in a library, for example.%@AE@%%@NL@%
  5796. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  5797. %@NL@%
  5798. %@NL@%
  5799. %@4@%%@AB@%Extension Search Paths%@AE@%%@EH@%%@NL@%
  5800. %@NL@%
  5801. If an inference rule does not specify a search path, as in the example
  5802. above, NMAKE looks for files in the current directory. You can specify a
  5803. single path for each of the extensions, using the following form:  %@NL@%
  5804. %@NL@%
  5805. %@AS@%  {frompath}. fromext{topath}. toext:
  5806. %@AS@%          commands%@AE@%%@NL@%
  5807. %@NL@%
  5808. NMAKE searches in the %@AI@%frompath%@AE@% directory for files with the %@AI@%fromext%@AE@%
  5809. extension. It uses %@AI@%commands%@AE@% to create files with the %@AI@%toext%@AE@% extension in the
  5810. %@AI@%topath%@AE@% directory.  %@NL@%
  5811. %@NL@%
  5812. %@NL@%
  5813. %@4@%%@AB@%Predefined Inference Rules%@AE@%%@EH@%%@NL@%
  5814. %@NL@%
  5815. NMAKE provides predefined inference rules to perform these common
  5816. development tasks:  %@NL@%
  5817. %@NL@%
  5818. %@NL@%
  5819.   ■   Creating an .OBJ file by compiling a .C file%@NL@%
  5820. %@NL@%
  5821.   ■   Creating an .OBJ file by assembling an .ASM file%@NL@%
  5822. %@NL@%
  5823.   ■   Creating an .EXE file by compiling a .C file and linking the resulting
  5824.       .OBJ file%@NL@%
  5825. %@NL@%
  5826. %@NL@%
  5827. Table 6.3 describes the predefined inference rules.  %@NL@%
  5828. %@NL@%
  5829. %@AB@%Table   %@AB@%6.3 Predefined Inference Rules%@AE@%%@AE@%
  5830.  
  5831. %@TH:   6   432 02 16 26 34 @%
  5832. Inference Rule  Command                   Default Action
  5833. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5834. .c.obj          $(CC) $(CFLAGS) /c $*.c   cl /c $*.c
  5835. .asm.obj        $(AS) $(AFLAGS) $*;       masm $*;
  5836. .c.exe          $(CC) $(CFLAGS) $*.c      cl $*.c
  5837. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5838. %@TE:   6   432 02 16 26 34 @%
  5839.  
  5840. For example, say that you have the following description file:  %@NL@%
  5841. %@NL@%
  5842. %@AS@%  sample.exe :%@AE@%%@NL@%
  5843. %@NL@%
  5844. Like the previous example, this description block lists a target without any
  5845. dependents or commands. NMAKE looks at the target's extension (.EXE) and
  5846. checks for an inference rule that describes how to create a .EXE file. The
  5847. last rule in Table 6.3 provides this information:  %@NL@%
  5848. %@NL@%
  5849. %@AS@%  .c.exe:
  5850. %@AS@%     $(CC) $(CFLAGS) $*.c%@AE@%%@NL@%
  5851. %@NL@%
  5852. To apply this rule, NMAKE first looks for a file with the same base name as
  5853. the target (SAMPLE) and the .C extension. If SAMPLE.C exists in the current
  5854. directory, NMAKE executes the CL command given in the rule. The command
  5855. compiles SAMPLE.C and links the resulting file SAMPLE.OBJ to create
  5856. SAMPLE.EXE.  %@NL@%
  5857. %@NL@%
  5858. %@NL@%
  5859. %@4@%%@AB@%Precedence among Inference Rules%@AE@%%@EH@%%@NL@%
  5860. %@NL@%
  5861. If the same inference rule is defined in more than one place, NMAKE uses the
  5862. rule with the highest precedence. The precedence from highest to lowest is  %@NL@%
  5863. %@NL@%
  5864. %@NL@%
  5865.   1.  Inference rules defined in the description file%@NL@%
  5866. %@NL@%
  5867.   2.  Inference rules defined in the TOOLS.INI file%@NL@%
  5868. %@NL@%
  5869.   3.  Predefined inference rules%@NL@%
  5870. %@NL@%
  5871. %@NL@%
  5872. NMAKE uses a predefined inference rule only if no user-defined inference
  5873. rule exists for the desired operation.  %@NL@%
  5874. %@NL@%
  5875. %@NL@%
  5876. %@3@%%@CR:C6A00060011 @%%@AB@%6.3.5  Directives%@AE@%%@EH@%%@NL@%
  5877. %@NL@%
  5878. Directives allow you to write description files that are similar to batch
  5879. files. Directives can execute commands conditionally, display error
  5880. messages, include other files, and turn on or off certain options.  %@NL@%
  5881. %@NL@%
  5882. %@AU@% NMAKE directives are similar to C preprocessor directives.%@AE@%  %@NL@%
  5883. %@NL@%
  5884. A directive begins with an exclamation point (!), which must appear at the
  5885. beginning of the line. You can place spaces between the exclamation point
  5886. and the directive keyword. (See Table 6.4.)  %@NL@%
  5887. %@NL@%
  5888. %@AB@%Table 6.4  %@AB@%Directives%@AE@%%@AE@%
  5889.  
  5890. %@TH:  49  3078 02 25 51 @%
  5891. Directive                Description
  5892. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5893. !CMDSWITCHES             Turns on or off one of four NMAKE options: /D, /I,
  5894. {%@AB@%+%@AE@%| %@AB@%-%@AE@%}%@AI@%opt%@AE@%...             
  5895.                           /N, and /S. If no options are specified, the 
  5896.                          options are reset to the way they were when NMAKE
  5897.                          started. Turn an option on by preceding it with a
  5898.                          plus sign (+), or turn it off by preceding it 
  5899.                          with a minus sign (-). Using this keyword updates
  5900.                          the %@AB@%MAKEFLAGS%@AE@% macro.
  5901.  
  5902. !ELSE                    Executes the statements between the%@AB@% !ELSE%@AE@% and%@AB@% %@AE@%
  5903.                          %@AB@%!ENDIF%@AE@% keywords if the statements preceding the %@AB@%%@AE@%
  5904.                          %@AB@%!ELSE%@AE@% keyword were not executed.
  5905.  
  5906. !ENDIF                   Marks the end of the%@AB@% !IF%@AE@%,%@AB@% !IFDEF%@AE@%, or%@AB@% !IFNDEF%@AE@% 
  5907.                          block of statements.
  5908.  
  5909. !ERROR %@AI@%text%@AE@%              Causes %@AI@%text%@AE@% to be printed and then stops 
  5910.                          execution.
  5911.  
  5912. !IF %@AI@%constantexpression%@AE@%   Executes the statements between the%@AB@% !IF %@AE@%keyword 
  5913.                          and the next %@AB@%!ELSE%@AE@% or %@AB@%!ENDIF%@AE@% keyword if %@AI@%constant%@AE@%
  5914.                          %@AI@%expression%@AE@% evaluates to a nonzero value.
  5915.  
  5916. !IFDEF %@AI@%macroname%@AE@%         Executes the statements between the %@AB@%!IFDEF%@AE@% 
  5917.                          keyword and the next%@AB@% !ELSE%@AE@% or%@AB@% !ENDIF %@AE@%keyword if %@AI@%%@AE@%
  5918.                          %@AI@%macroname%@AE@% is defined. NMAKE considers a macro 
  5919.                          with a null value to be defined.
  5920.  
  5921. !IFNDEF %@AI@%macroname%@AE@%        Executes the statements between the%@AB@% !IFNDEF%@AE@% 
  5922.                          keyword and the next%@AB@% !ELSE%@AE@% or %@AB@%!ENDIF%@AE@% keyword if %@AI@%%@AE@%
  5923.                          %@AI@%macroname%@AE@% is not defined.
  5924.  
  5925. !INCLUDE %@AI@%filename%@AE@%        Reads and evaluates the file %@AI@%filename%@AE@% before 
  5926.                          continuing with the current description file. If %@AI@%%@AE@%
  5927.                          %@AI@%filename%@AE@% is enclosed by angle brackets (< >), 
  5928.                          NMAKE searches for the file in the directories 
  5929.                          specified by the %@AB@%INCLUDE%@AE@% macro. Otherwise, it 
  5930.                          looks only in the current directory. The %@AB@%%@AE@%
  5931.                          %@AB@%INCLUDE%@AE@% macro is initially set to the value of 
  5932.                          the
  5933.                          INCLUDE environment variable.
  5934.  
  5935. !UNDEF %@AI@%macroname%@AE@%         Marks %@AI@%macroname%@AE@% as being undefined in NMAKE's 
  5936.                          symbol table.
  5937.  
  5938. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5939.  
  5940. %@TE:  49  3078 02 25 51 @%
  5941.  
  5942. The %@AI@%constantexpression%@AE@% used with the %@AB@%!IF%@AE@% directive can consist of integer
  5943. constants, string constants, or program invocations. Integer constants can
  5944. use the C unary operators for numerical negation (%@AB@%-%@AE@%), one's complement (%@AB@%~%@AE@%),
  5945. and logical negation (%@AB@%!%@AE@%). They can also use any of the C binary operators
  5946. listed in Table 6.5.  %@NL@%
  5947. %@NL@%
  5948. %@AB@%Table 6.5  %@AB@%Directive Operators%@AE@%%@AE@%
  5949.  
  5950. %@TH:  21  1088 02 22 54 @%
  5951. Operator              Description
  5952. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5953. %@AB@%+%@AE@%                     Addition
  5954. %@AB@%-%@AE@%                     Subtraction
  5955. %@AB@%*%@AE@%                     Multiplication
  5956. %@AB@%/%@AE@%                     Division
  5957. %@AB@%%%@AE@%                     Modulus
  5958. %@AB@%&%@AE@%                     Bitwise AND
  5959. %@AB@%|%@AE@%                     Bitwise OR
  5960. %@AB@%^^%@AE@%                    Bitwise XOR
  5961. %@AB@%&&%@AE@%                    Logical AND
  5962. %@AB@%||%@AE@%                    Logical OR
  5963. %@AB@%<<%@AE@%                    Left shift
  5964. %@AB@%>>%@AE@%                    Right shift
  5965. %@AB@%==%@AE@%                    Equality
  5966. %@AB@%!=%@AE@%                    Inequality
  5967. %@AB@%<%@AE@%                     Less than
  5968. %@AB@%>%@AE@%                     Greater than
  5969. %@AB@%<=%@AE@%                    Less than or equal to
  5970. %@AB@%>=%@AE@%                    Greater than or equal to
  5971. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5972. %@TE:  21  1088 02 22 54 @%
  5973.  
  5974. You can group expressions using parentheses. NMAKE treats numbers as decimal
  5975. unless they start with 0 (octal) or 0x (hexadecimal). Use the equality (%@AB@%==%@AE@%)
  5976. operator to compare two strings for equality or the inequality (%@AB@%!=%@AE@%) operator
  5977. to compare for inequality. Enclose strings with quotes. Program invocations
  5978. must be in square brackets ([ ]).  %@NL@%
  5979. %@NL@%
  5980. The following example illustrates directives:  %@NL@%
  5981. %@NL@%
  5982. %@AS@%  !INCLUDE <infrules.txt>
  5983. %@AS@%  !CMDSWITCHES +D
  5984. %@AS@%  winner.exe:winner.obj
  5985. %@AS@%  !IFDEF debug
  5986. %@AS@%  !  IF "$(debug)"=="y"
  5987. %@AS@%       LINK /CO winner.obj;
  5988. %@AS@%  !  ELSE
  5989. %@AS@%       LINK winner.obj;
  5990. %@AS@%  !  ENDIF
  5991. %@AS@%  !ELSE
  5992. %@AS@%  !  ERROR Macro named debug is not defined.
  5993. %@AS@%  !ENDIF%@AE@%%@NL@%
  5994. %@NL@%
  5995. The !INCLUDE directive causes NMAKE to insert the file INFRULES.TXT into the
  5996. description file. The !CMDSWITCHES directive turns on the /D option, which
  5997. displays the dates of the files as they are checked. If WINNER.EXE is
  5998. out-of-date with respect to WINNER.OBJ, the !IFDEF directive checks to see
  5999. if the macro %@AS@% debug %@AE@% is defined. If it is defined, the !IF directive checks
  6000. to see if it is set to %@AS@% y%@AE@%. If it is, the linker is invoked with the /CO
  6001. option; otherwise it is invoked without. If the %@AS@% debug %@AE@% macro is not
  6002. defined, the !ERROR directive prints the message and NMAKE stops.  %@NL@%
  6003. %@NL@%
  6004. %@NL@%
  6005. %@3@%%@CR:C6A00060012 @%%@AB@%6.3.6  Pseudotargets%@AE@%%@EH@%%@NL@%
  6006. %@NL@%
  6007. Pseudotargets are useful for building a group of files or executing a group
  6008. of commands.%@CR:C6A00060013 @%  %@NL@%
  6009. %@NL@%
  6010. A "pseudotarget" is similar to a target, but it is not a file. It is a name
  6011. that serves as a "handle" for building a group of files or executing a group
  6012. of commands. In the following example, %@AS@% UPDATE %@AE@% is a pseudotarget.  %@NL@%
  6013. %@NL@%
  6014. %@AS@%  UPDATE: *.*
  6015. %@AS@%   !COPY $** a:\product%@AE@%%@NL@%
  6016. %@NL@%
  6017. When NMAKE evaluates a pseudotarget, it always considers the dependents to
  6018. be out-of-date. In the example, NMAKE copies each of the dependent files to
  6019. the specified drive and directory.  %@NL@%
  6020. %@NL@%
  6021. Like macro names, pseudotarget names are case sensitive. Predefined
  6022. pseudotarget names are all uppercase.  %@NL@%
  6023. %@NL@%
  6024. The pseudotargets in Table 6.6 are predefined to provide special rules in a
  6025. description file. You can use their names on the command line, in a
  6026. description file, or in the TOOLS.INI file. You need not specify them as
  6027. targets; NMAKE uses the rules they define no matter where they appear.%@CR:C6A00060014 @%  %@NL@%
  6028. %@NL@%
  6029. %@AB@%Table   %@AB@%6.6  Pseudotargets%@AE@%%@AE@%
  6030.  
  6031. %@TH:  50  3027 02 34 42 @%
  6032. Pseudotarget                      Action
  6033. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6034. .IGNORE:                          Ignores exit codes returned by programs 
  6035.                                   called from the description file. Same 
  6036.                                   effect as invoking NMAKE with the /I 
  6037.                                   option.
  6038.  
  6039. .PRECIOUS: %@AI@%target(s)%@AE@%              Tells NMAKE not to delete %@AI@%target(s)%@AE@% if 
  6040.                                   the commands that build it are quit or 
  6041.                                   interrupted. Using this pseudotarget 
  6042.                                   overrides the NMAKE default. By default,
  6043.                                   NMAKE deletes the target if it cannot be
  6044.                                   sure the target is built successfully.
  6045.  
  6046.                                   The .PRECIOUS pseudotarget is rarely 
  6047.                                   needed. Like most professional tools, 
  6048.                                   Microsoft language tools clean up by 
  6049.                                   themselves when errors occur.
  6050.  
  6051. .SILENT:                          Does not display lines as they are 
  6052.                                   executed. Same effect as invoking NMAKE 
  6053.                                   with the /S option.
  6054.  
  6055. .SUFFIXES:%@AI@%list%@AE@%                    Lists file suffixes for NMAKE to try 
  6056.                                   when building a target file for which no
  6057.                                   dependents are specified. This list is 
  6058.                                   used together with inference rules. See 
  6059.                                   Section 6.3.4, "Inference Rules."
  6060.  
  6061.                                   When NMAKE finds a target without any 
  6062.                                   dependents, it searches the current 
  6063.                                   directory for a file with the same base 
  6064.                                   name as the target and a suffix from the
  6065.                                   list. If NMAKE finds such a file, and if
  6066.                                   an inference rule applies to the file, 
  6067.                                   then NMAKE treats the file as a depen-
  6068.                                   dent of the target. The order of the 
  6069.                                   suffixes in the list defines the order 
  6070.                                   in which NMAKE searches for the file. 
  6071.                                   The list is predefined as follows:
  6072.  
  6073.                                   %@AS@%.SUFFIXES: .obj .exe .c .asm%@AE@%
  6074.  
  6075.                                   To add suffixes to the list, specify %@AS@% %@AE@%
  6076.                                   %@AS@%.SUFFIXES : %@AE@%
  6077.                                   followed by the new suffixes. To clear 
  6078.                                   the list, specify %@AS@% .SUFFIXES:%@AE@%
  6079.  
  6080. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6081.  
  6082. %@TE:  50  3027 02 34 42 @%
  6083.  
  6084. %@NL@%
  6085. %@3@%%@CR:C6A00060015 @%%@AB@%6.3.7  PWB's extmake Syntax%@AE@%%@EH@%%@NL@%
  6086. %@NL@%
  6087. NMAKE description files can use the same syntax as the %@AB@%extmake%@AE@% switch of PWB
  6088. (see Chapter 8, "Customizing the Microsoft Programmer's WorkBench"). This
  6089. syntax allows you to determine the drive, path, base name, and extension of
  6090. the first dependent, information that is not otherwise available. The file
  6091. name, and parts of its name, are represented using the syntax  %@NL@%
  6092. %@NL@%
  6093. %@AS@%  %|partsF%@AE@%%@NL@%
  6094. %@NL@%
  6095. where %@AI@%parts%@AE@% is one or more of the following:  %@NL@%
  6096. %@NL@%
  6097. %@AB@%Letter%@AE@%                            %@AB@%Description%@AE@%
  6098. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6099. %@AB@%d%@AE@%                                 Drive
  6100.  
  6101. %@AB@%e%@AE@%                                 File extension
  6102.  
  6103. %@AB@%f%@AE@%                                 File base name
  6104.  
  6105. %@AB@%p%@AE@%                                 Path
  6106.  
  6107. %@AB@%s%@AE@%                                 Complete name
  6108.  
  6109. The following example uses %@AB@%extmake%@AE@% syntax:  %@NL@%
  6110. %@NL@%
  6111. %@AS@%  sample.obj : sample.c
  6112. %@AS@%     CL /Fod:%|pfF %|dfeF%@AE@%%@NL@%
  6113. %@NL@%
  6114. In this example, the sequence %@AS@% %|pfF %@AE@% represents the path and base name of
  6115. the first dependent file, while the sequence %@AS@% %|dfeF %@AE@% represents the drive,
  6116. base name, and extension of the same file. The example, then, compiles the
  6117. file and writes the output to a file on the same path but with the default
  6118. .OBJ extension.  %@NL@%
  6119. %@NL@%
  6120. The percent symbol (%) is a replacement character in DOS and OS/2 command
  6121. lines in the description file. To use %@AB@%extmake%@AE@% syntax in command-line
  6122. arguments, specify each percent symbol as a double percent symbol (%%).  %@NL@%
  6123. %@NL@%
  6124. %@NL@%
  6125. %@2@%%@CR:C6A00060016 @%%@AB@%6.4  Command-Line Options%@AE@%%@EH@%%@NL@%
  6126. %@NL@%
  6127. NMAKE accepts a number of options, which are listed in Table 6.7. You can
  6128. specify options in uppercase or lowercase and use either a slash or dash.
  6129. For example, -A, /A, -a, and /a all represent the same option.  %@NL@%
  6130. %@NL@%
  6131. %@AB@%Table   %@AB@%6.7 NMAKE Options%@AE@%%@AE@%
  6132.  
  6133. %@TH:  73  3813 02 34 42 @%
  6134. Option                            Action
  6135. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6136. /A                                Builds all of the requested targets even
  6137.                                   if they are not out-of-date.
  6138.  
  6139. /C                                Suppresses nonfatal error or warning 
  6140.                                   messages and the NMAKE logo display.
  6141.  
  6142. /D                                Displays the modification date of each 
  6143.                                   file.
  6144.  
  6145. /E                                Causes environment variables to override
  6146.                                   macro definitions in description files. 
  6147.                                   See Section 6.3.3, "Macros."
  6148.  
  6149. /F %@AI@%filename%@AE@%                       Specifies %@AI@%filename%@AE@% as the name of the 
  6150.                                   description file. If you supply a dash 
  6151.                                   (-) instead of a file name, NMAKE gets 
  6152.                                   input from the standard input device 
  6153.                                   instead of the description file.
  6154.  
  6155. /HELP                             Calls the QuickHelp utility. If the 
  6156.                                   QuickHelp program is not available, 
  6157.                                   NMAKE displays the most commonly used 
  6158.                                   NMAKE options.
  6159.  
  6160. /I                                Ignores return codes from commands 
  6161.                                   listed in the description file. NMAKE 
  6162.                                   processes the whole description file 
  6163.                                   even if errors occur.
  6164.  
  6165. /N                                Displays but does not execute the 
  6166.                                   description file's commands. This option
  6167.                                   is useful for debugging description 
  6168.                                   files and checking which targets are 
  6169.                                   out-of-date.
  6170.  
  6171. /NOLOGO                           Suppresses the NMAKE logo display.
  6172.  
  6173. /P                                Displays all macro definitions and 
  6174.                                   target descriptions on the standard 
  6175.                                   output device.
  6176.  
  6177. /Q                                Returns zero if the target is up-to-date
  6178.                                   and nonzero if it is not. This option is
  6179.                                   useful when running NMAKE from a batch 
  6180.                                   file.
  6181.  
  6182. /R                                Ignores inference rules and macros that 
  6183.                                   are predefined or defined in the 
  6184.                                   TOOLS.INI file.
  6185.  
  6186. /S                                Suppresses the display of commands 
  6187.                                   listed in the description file.
  6188.  
  6189. /T                                Changes the modification dates for 
  6190.                                   out-of-date target files to the current 
  6191.                                   date.
  6192.  
  6193. /X %@AI@%filename%@AE@%                       Sends all error output to %@AI@%filename%@AE@%, 
  6194.                                   which can be a file or a device. If you 
  6195.                                   supply a dash (-) instead of a file name,
  6196.                                   the error output is sent to the standard
  6197.                                   output device.
  6198.  
  6199. /Z                                Used for internal communication between 
  6200.                                   NMAKE and PWB.
  6201.  
  6202. /?                                Displays a brief summary of NMAKE syntax
  6203.                                   and exits to the operating system.
  6204.  
  6205. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6206.  
  6207. %@TE:  73  3813 02 34 42 @%
  6208.  
  6209. The following command specifies two NMAKE options:  %@NL@%
  6210. %@NL@%
  6211. %@AS@%  NMAKE /f sample.mak /c targ1 targ2%@AE@%%@NL@%
  6212. %@NL@%
  6213. The /f option tells NMAKE to read the description file SAMPLE.MAK. The /c
  6214. option tells NMAKE not to display nonfatal error messages and warnings. The
  6215. command lists two targets (%@AS@%targ1 %@AE@% and %@AS@% targ2%@AE@%) to update.  %@NL@%
  6216. %@NL@%
  6217. %@AS@%  NMAKE  /D /N targ1 targ1.mak%@AE@%%@NL@%
  6218. %@NL@%
  6219. In the example above, NMAKE updates the target %@AS@% targ1%@AE@%. If the current
  6220. directory does not contain a file named MAKEFILE, NMAKE reads the file
  6221. TARG1.MAK as the description file. The /D option displays the modification
  6222. date of each file; the /N option displays the commands without executing
  6223. them.  %@NL@%
  6224. %@NL@%
  6225. %@NL@%
  6226. %@2@%%@CR:C6A00060017 @%%@AB@%6.5  NMAKE Command Files%@AE@%%@EH@%%@NL@%
  6227. %@NL@%
  6228. Occasionally, you may need to give NMAKE a long list of command-line
  6229. arguments that exceeds the maximum length of a command line (128 characters
  6230. in DOS, 256 in OS/2). To do this, place the command arguments in a file,
  6231. then give the name of the file when you run NMAKE.  %@NL@%
  6232. %@NL@%
  6233. For instance, say that you create a file named UPDATE, which consists of
  6234. this line:  %@NL@%
  6235. %@NL@%
  6236. %@AS@%  /S "program = sample" sort.exe search.exe%@AE@%%@NL@%
  6237. %@NL@%
  6238. If you start NMAKE with the command  %@NL@%
  6239. %@NL@%
  6240. %@AS@%  NMAKE @update%@AE@%%@NL@%
  6241. %@NL@%
  6242. NMAKE reads its command-line arguments from UPDATE. The at sign (@) tells
  6243. NMAKE to read arguments from the file. The effect is the same as if you
  6244. typed the arguments directly on the command line:  %@NL@%
  6245. %@NL@%
  6246. %@AS@%  NMAKE /S "program = sample" sort.exe search.exe%@AE@%%@NL@%
  6247. %@NL@%
  6248. Within the file, line breaks between arguments are treated as spaces. Macro
  6249. definitions that contain spaces must be enclosed in quotation marks, just as
  6250. if you typed them on the command line. You can continue a macro definition
  6251. across multiple lines by ending each line except the last with a backslash (
  6252. \ ):  %@NL@%
  6253. %@NL@%
  6254. %@AS@%  /S "program \
  6255. %@AS@%  = sample" sort.exe search.exe%@AE@%%@NL@%
  6256. %@NL@%
  6257. This file is equivalent to the first example. The backslash in the example
  6258. allows the macro definition (%@AS@%"program = sample" %@AE@%) to span two lines.  %@NL@%
  6259. %@NL@%
  6260. %@NL@%
  6261. %@2@%%@CR:C6A00060018 @%%@AB@%6.6  The TOOLS.INI File%@AE@%%@EH@%%@NL@%
  6262. %@NL@%
  6263. You can customize NMAKE by placing commonly used macros and inference rules
  6264. in the TOOLS.INI initialization file. Settings for NMAKE must follow a line
  6265. that begins with %@AS@% [NMAKE]%@AE@%. This part of the initialization file can contain
  6266. macro definitions, .SUFFIXES lists, and inference rules. For example,  %@NL@%
  6267. %@NL@%
  6268. %@AS@%  [NMAKE]
  6269. %@AS@%  CC=cl
  6270. %@AS@%  CFLAGS=-Gc -Gs -W3 -Oat
  6271. %@AS@%  .c.obj:
  6272. %@AS@%      $(CC) -c $(CFLAGS) $*.c%@AE@%%@NL@%
  6273. %@NL@%
  6274. If TOOLS.INI contains the code above, NMAKE reads and applies the lines
  6275. following %@AS@% [NMAKE]%@AE@%. The example defines the macros %@AB@%CC%@AE@% and %@AB@%CFLAGS%@AE@% and
  6276. redefines the inference rule for making .OBJ files from .C sources.  %@NL@%
  6277. %@NL@%
  6278. NMAKE looks for TOOLS.INI in the current directory. If it is not found
  6279. there, NMAKE searches the directory specified by the INIT environment
  6280. variable.  %@NL@%
  6281. %@NL@%
  6282. %@NL@%
  6283. %@2@%%@CR:C6A00060019 @%%@AB@%6.7  In-Line Files%@AE@%%@EH@%%@NL@%
  6284. %@NL@%
  6285. NMAKE can write "in-line files," which can contain any text you specify. One
  6286. use for in-line files is to write a response file for another utility such
  6287. as LIB. (Response files are useful when you need to supply a program with a
  6288. long list of arguments that exceeds the maximum length of the command line.)
  6289. %@NL@%
  6290. %@NL@%
  6291. Use this syntax to create an in-line file:  %@NL@%
  6292. %@NL@%
  6293. %@AS@%  target : dependents
  6294. %@AS@%     command << «filename»
  6295. %@AS@%  inlinetext
  6296. %@AS@%  <<«KEEP | NOKEEP»%@AE@%%@NL@%
  6297. %@NL@%
  6298. All of the text between the two sets of double angle brackets (%@AB@%%@AE@%) is placed
  6299. in the in-line file. The %@AI@%filename%@AE@% is optional. If you don't supply %@AI@%filename%@AE@%,
  6300. NMAKE gives the in-line file a unique name. NMAKE places the in-line file in
  6301. the current directory or, if the TMP environment variable is defined, in the
  6302. directory specified by TMP.  %@NL@%
  6303. %@NL@%
  6304. The in-line file can be temporary or permanent. If you don't specify
  6305. otherwise, or if you specify %@AB@%NOKEEP%@AE@%, it is temporary. Specify %@AB@%KEEP%@AE@% to retain
  6306. the file.  %@NL@%
  6307. %@NL@%
  6308. The following example creates a LIB response file named LIB.LRF:  %@NL@%
  6309. %@NL@%
  6310. %@AS@%  math.lib : add.obj sub.obj mul.obj div.obj
  6311. %@AS@%    LIB @<<lib.lrf
  6312. %@AS@%  math.lib
  6313. %@AS@%  -+add.obj-+sub.obj-+mul.obj-+div.obj
  6314. %@AS@%  listing
  6315. %@AS@%  <<KEEP%@AE@%%@NL@%
  6316. %@NL@%
  6317. The resulting response file tells LIB which library to use, the commands to
  6318. execute, and the listing file to produce:  %@NL@%
  6319. %@NL@%
  6320. %@AS@%  math.lib
  6321. %@AS@%  -+add.obj-+sub.obj-+mul.obj-+div.obj
  6322. %@AS@%  listing%@AE@%%@NL@%
  6323. %@NL@%
  6324. The in-line file specification can create more than one in-line file. For
  6325. instance,  %@NL@%
  6326. %@NL@%
  6327. %@AS@%  target.abc : depend.xyz
  6328. %@AS@%     cat <<file1 <<file2
  6329. %@AS@%  I am the contents of file1.
  6330. %@AS@%  <<KEEP
  6331. %@AS@%  I am the contents of file2.
  6332. %@AS@%  <<KEEP%@AE@%%@NL@%
  6333. %@NL@%
  6334. The example creates two in-line files named FILE1 and FILE2; then NMAKE
  6335. executes the command:  %@NL@%
  6336. %@NL@%
  6337. %@AS@%  CAT file1 file2%@AE@%%@NL@%
  6338. %@NL@%
  6339. The %@AB@%KEEP%@AE@% keywords tell NMAKE not to delete FILE1 and FILE2 when done.  %@NL@%
  6340. %@NL@%
  6341. %@NL@%
  6342. %@2@%%@CR:C6A00060020 @%%@AB@%6.8  NMAKE Operations Sequence%@AE@%%@EH@%%@NL@%
  6343. %@NL@%
  6344. If you are writing a complex description file, you may need to know the
  6345. exact order of steps that NMAKE follows. This section describes those steps
  6346. in order.  %@NL@%
  6347. %@NL@%
  6348. When you run NMAKE from the command line, its first task is to find the
  6349. description file, following these steps:  %@NL@%
  6350. %@NL@%
  6351. %@NL@%
  6352.   1.  If NMAKE is invoked with the /F option, it uses the file name
  6353.       specified in the option.%@NL@%
  6354. %@NL@%
  6355.   2.  If /F is not specified, NMAKE looks for a file named MAKEFILE in the
  6356.       current directory. If such a file exists, it is used as a description
  6357.       file.%@NL@%
  6358. %@NL@%
  6359.   3.  If MAKEFILE is not in the current directory, NMAKE parses the command
  6360.       line for the first string that is not an option or a macro definition
  6361.       and treats this string as a file name. If the file-name extension does
  6362.       not appear in the .SUFFIXES list, NMAKE uses the file as the
  6363.       description file. If the extension appears in the .SUFFIXES list,
  6364.       NMAKE tries additional strings until it finds a suitable file. (See
  6365.       Section 6.3.6, "Pseudotargets," for a description of the .SUFFIXES
  6366.       list.)%@NL@%
  6367. %@NL@%
  6368.   4.  If NMAKE still has not found a description file, it returns an error.%@NL@%
  6369. %@NL@%
  6370. %@NL@%
  6371. NMAKE stops searching for a description file as soon as it finds one, even
  6372. if other potential description files exist. If you specify /F, NMAKE uses
  6373. the file specified by that option even if MAKEFILE exists in the current
  6374. directory. Similarly, if NMAKE uses MAKEFILE, any description file listed in
  6375. the command line is treated as a target.  %@NL@%
  6376. %@NL@%
  6377. %@AU@% If you do not specify targets, NMAKE updates only the first target in the
  6378. %@AU@%description file.%@AE@%  %@NL@%
  6379. %@NL@%
  6380. Next, NMAKE updates every target listed on the command line. If none is
  6381. listed, NMAKE updates only the first target in the description file. (This
  6382. behavior differs from the older MAKE program's default; see Section 6.9,
  6383. "Differences between NMAKE and MAKE.")  %@NL@%
  6384. %@NL@%
  6385. NMAKE then applies macro definitions and inference rules in the following
  6386. order, from highest to lowest priority:  %@NL@%
  6387. %@NL@%
  6388. %@NL@%
  6389.   1.  Macros defined on the command line%@NL@%
  6390. %@NL@%
  6391.   2.  Macros defined in a description file or include file%@NL@%
  6392. %@NL@%
  6393.   3.  Inherited macros%@NL@%
  6394. %@NL@%
  6395.   4.  Macros defined in the TOOLS.INI file%@NL@%
  6396. %@NL@%
  6397.   5.  Predefined macros such as %@AB@%CC%@AE@% and %@AB@%AS%@AE@%%@NL@%
  6398. %@NL@%
  6399. %@NL@%
  6400. Definitions in later steps take precedence over definitions in earlier
  6401. steps. The /E option, however, causes inherited macros to override macros
  6402. defined on the command line. The /R option causes NMAKE to ignore macros and
  6403. inference rules that are predefined or defined in TOOLS.INI.  %@NL@%
  6404. %@NL@%
  6405. Now NMAKE updates each target in the order in which it appears in the
  6406. description file. It compares the date and time of each dependent with that
  6407. of the target and performs the commands needed to update the target. If you
  6408. specify the /A option or if the target is a pseudotarget, NMAKE updates the
  6409. target even if its dependents are not out-of-date.  %@NL@%
  6410. %@NL@%
  6411. If the target has no explicit dependents, NMAKE looks in the current
  6412. directory for one or more files whose extensions are in the .SUFFIXES list.
  6413. If it finds such files, NMAKE treats them as dependents and updates the
  6414. target according to the commands.  %@NL@%
  6415. %@NL@%
  6416. If no commands are given to update the target or if the dependents cannot be
  6417. found, NMAKE applies inference rules to build the target. By default, it
  6418. tries to build .EXE files from .OBJ files; and it tries to build .OBJ files
  6419. from .C and .ASM sources. In practice, this means you should specify .OBJ
  6420. files as dependents, because NMAKE compiles your source files when it can't
  6421. find the .OBJ files.  %@NL@%
  6422. %@NL@%
  6423. NMAKE normally quits processing the description file when a command  returns
  6424. an error. In addition, if it cannot tell that the target was built
  6425. successfully, NMAKE deletes the partially created target. If you use the /I
  6426. commandline option, NMAKE ignores exit codes and attempts to continue
  6427. processing. The .IGNORE pseudotarget has the same effect. To prevent NMAKE
  6428. from  deleting the partially created target, specify the target name in the
  6429. .PRECIOUS pseudotarget.  %@NL@%
  6430. %@NL@%
  6431. Alternatively, you can use the dash (-) command modifier to ignore the error
  6432. code for an individual command. An optional number after the dash tells
  6433. NMAKE to continue if the command returns an error code that is less than or
  6434. equal to the number, and to stop if the error code is greater than the
  6435. number.  %@NL@%
  6436. %@NL@%
  6437. You can help document errors by using the !ERROR directive to print
  6438. descriptive text. The directive causes NMAKE to print some text, then stop,
  6439. even if you use /I, .IGNORE, or the dash (-) modifier.  %@NL@%
  6440. %@NL@%
  6441. %@NL@%
  6442. %@2@%%@CR:C6A00060021 @%%@AB@%6.9  Differences between NMAKE and MAKE%@AE@%%@EH@%%@NL@%
  6443. %@NL@%
  6444. As its name implies, NMAKE is a new utility that replaces the older
  6445. Microsoft MAKE program. NMAKE differs from MAKE in the following ways:  %@NL@%
  6446. %@NL@%
  6447. %@NL@%
  6448.   ■   NMAKE does not evaluate targets sequentially. Instead, NMAKE updates
  6449.       the targets you specify when you invoke it, regardless of their
  6450.       positions in the description file. If no targets are specified, NMAKE
  6451.       updates only the first target in the file.%@NL@%
  6452. %@NL@%
  6453.   ■   NMAKE accepts command-line arguments from a file.%@NL@%
  6454. %@NL@%
  6455.   ■   NMAKE provides more command-line options.%@NL@%
  6456. %@NL@%
  6457.   ■   NMAKE provides more predefined macros.%@NL@%
  6458. %@NL@%
  6459.   ■   NMAKE permits substitutions within macros.%@NL@%
  6460. %@NL@%
  6461.   ■   NMAKE supports directives placed in the description file.%@NL@%
  6462. %@NL@%
  6463.   ■   NMAKE allows you to specify include files in the description file.%@NL@%
  6464. %@NL@%
  6465. %@NL@%
  6466. The first item in the list deserves special emphasis. While MAKE normally
  6467. builds every target, working from beginning to end of the description file,
  6468. NMAKE expects you to specify targets on the command line. If you do not,
  6469. NMAKE builds only the first target in the description file.  %@NL@%
  6470. %@NL@%
  6471. The difference is clear if you run NMAKE using a typical MAKE description
  6472. file, which lists a series of subordinate targets followed by a higher-level
  6473. target that depends on the subordinates:  %@NL@%
  6474. %@NL@%
  6475. %@AS@%  pmapp.obj : pmapp.c
  6476. %@AS@%     CL /c /G2sw /W3 pmapp.c
  6477. %@AS@%  
  6478. %@AS@%  pmapp.exe : pmapp.obj pmapp.def
  6479. %@AS@%     LINK pmapp, /align:16, NUL, os2, pmapp%@AE@%%@NL@%
  6480. %@NL@%
  6481. MAKE builds both targets (PMAPP.OBJ and PMAPP.EXE), but NMAKE builds only
  6482. the first target (PMAPP.OBJ).  %@NL@%
  6483. %@NL@%
  6484. Because of these performance differences, you may want to convert MAKE files
  6485. to NMAKE files. MAKE description files are easy to convert. A simple method
  6486. is to create a new description block at the beginning of the file. Give this
  6487. block a pseudotarget named %@AS@% ALL %@AE@% and list the top-level target as a
  6488. dependent of %@AS@% ALL%@AE@%. To build %@AS@% ALL%@AE@%, NMAKE must update every target upon which
  6489. the target of %@AS@% ALL %@AE@% depends:  %@NL@%
  6490. %@NL@%
  6491. %@AS@%  ALL : pmapp.exe
  6492. %@AS@%  
  6493. %@AS@%  pmapp.obj : pmapp.c
  6494. %@AS@%     CL /c /G2sw /W3 pmapp.c
  6495. %@AS@%  
  6496. %@AS@%  pmapp.exe : pmapp.obj pmapp.def
  6497. %@AS@%     LINK pmapp, /align:16, NUL, os2, pmapp%@AE@%%@NL@%
  6498. %@NL@%
  6499. If the above file is named MAKEFILE, you can update the target PMAPP.EXE
  6500. with the command  %@NL@%
  6501. %@NL@%
  6502. %@AS@%  NMAKE%@AE@%%@NL@%
  6503. %@NL@%
  6504. or the command  %@NL@%
  6505. %@NL@%
  6506. %@AS@%  NMAKE ALL%@AE@%%@NL@%
  6507. %@NL@%
  6508. Note that it is not necessary to list PMAPP.OBJ as a dependent of %@AS@% ALL%@AE@%.
  6509. NMAKE builds a dependency tree for the entire description file, and builds
  6510. whatever files are needed to update PMAPP.EXE. So if PMAPP.C is out-ofdate
  6511. with respect to PMAPP.OBJ, NMAKE compiles PMAPP.C to create PMAPP.OBJ, then
  6512. links PMAPP.OBJ to create PMAPP.EXE.  %@NL@%
  6513. %@NL@%
  6514. The same technique is suitable for description files with more than one
  6515. top-level target. List all of the top-level targets as dependents of %@AS@% ALL%@AE@%:  %@NL@%
  6516. %@NL@%
  6517. %@AS@%  ALL : pmapp.exe second.exe another.exe%@AE@%%@NL@%
  6518. %@NL@%
  6519. The example updates the targets PMAPP.EXE, SECOND.EXE, and ANOTHER.EXE.  %@NL@%
  6520. %@NL@%
  6521. If the description file lists a single, top-level target, you can use an
  6522. even simpler technique. Move the top-level block to the beginning of the
  6523. file:  %@NL@%
  6524. %@NL@%
  6525. %@AS@%  pmapp.exe : pmapp.obj pmapp.def
  6526. %@AS@%     LINK pmapp, /align:16, NUL, os2, pmapp
  6527. %@AS@%  
  6528. %@AS@%  pmapp.obj : pmapp.c
  6529. %@AS@%     CL /c /G2sw /W3 pmapp.c%@AE@%%@NL@%
  6530. %@NL@%
  6531. NMAKE updates the second target (PMAPP.OBJ) whenever needed to keep the
  6532. first target (PMAPP.EXE) current.  %@NL@%
  6533. %@NL@%
  6534. %@NL@%
  6535. %@NL@%
  6536. %@NL@%
  6537. %@NL@%
  6538. %@NL@%
  6539. %@CR:C6A00070001 @%%@1@%%@AB@%Chapter 7  Creating Help Files with HELPMAKE%@AE@%%@EH@%%@NL@%
  6540. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6541. %@NL@%
  6542. If you have used PWB or other Microsoft language products such as QuickC,
  6543. you are familiar with the many advantages of on-line help. The Microsoft
  6544. Help-File-Creation Utility (HELPMAKE) allows you to create your own help
  6545. files for use with Microsoft products. It also allows you to customize the
  6546. help files supplied with Microsoft language products.  %@NL@%
  6547. %@NL@%
  6548. HELPMAKE translates help text files into a help database accessible from
  6549. within the following:  %@NL@%
  6550. %@NL@%
  6551. %@NL@%
  6552.   ■   Microsoft C 6.0 Programmer's WorkBench (PWB)%@NL@%
  6553. %@NL@%
  6554.   ■   QuickHelp Utility%@NL@%
  6555. %@NL@%
  6556.   ■   Microsoft Editor 1.02%@NL@%
  6557. %@NL@%
  6558.   ■   Microsoft QuickC 2.0%@NL@%
  6559. %@NL@%
  6560.   ■   Microsoft QuickPascal 1.0%@NL@%
  6561. %@NL@%
  6562.   ■   Microsoft QuickBASIC 4.5%@NL@%
  6563. %@NL@%
  6564. %@NL@%
  6565. This chapter describes how to create and modify help files using the
  6566. HELPMAKE utility.  %@NL@%
  6567. %@NL@%
  6568. %@NL@%
  6569. %@2@%%@CR:C6A00070002 @%%@AB@%7.1  Structure and Contents of a Help Database%@AE@%%@EH@%%@NL@%
  6570. %@NL@%
  6571. HELPMAKE creates a help database from one or more input files that contain
  6572. information formatted for the help system. This section defines some of the
  6573. terms involved in formatting and outlines the formats that HELPMAKE can
  6574. process.  %@NL@%
  6575. %@NL@%
  6576. %@NL@%
  6577. %@3@%%@CR:C6A00070003 @%%@AB@%7.1.1  Contents of a Help File%@AE@%%@EH@%%@NL@%
  6578. %@NL@%
  6579. As you might expect, each help text file starts with a topic and some
  6580. information about the topic, then lists another topic and some information
  6581. about it, and so on. In HELPMAKE terminology, topics are called "contexts";
  6582. the information is called "topic text."  %@NL@%
  6583. %@NL@%
  6584. The %@AB@%.context%@AE@% command introduces a context. In the source file for C 6.0
  6585. help, for example, this line introduces help for the %@AB@%open%@AE@% function:  %@NL@%
  6586. %@NL@%
  6587. %@AS@%  .context open%@AE@%%@NL@%
  6588. %@NL@%
  6589. The %@AB@%.context%@AE@% command and other formatting elements are described in Section
  6590. 7.5, "Help Text Conventions."  %@NL@%
  6591. %@NL@%
  6592. Whether a context is one or several words depends on the application.
  6593. QuickBASIC, for example, considers spaces to be delimiters, so in QuickBASIC
  6594. help files contexts are limited to a single word. Other applications, such
  6595. as the Microsoft Editor, can handle contexts that span several words. Either
  6596. way, the application simply hands the context to an internal "help engine,"
  6597. which searches the database for information.  %@NL@%
  6598. %@NL@%
  6599. Often, especially with library routines, the same information applies to
  6600. more than one subject. For example, the string-to-number functions %@AB@%strtod%@AE@%,
  6601. %@AB@%strtol%@AE@%, and %@AB@%stroul%@AE@% share the same help text. The help file lists all three
  6602. function names as contexts for one block of topic text. The converse,
  6603. however, is not true. You cannot specify different blocks of topic text, in
  6604. different places in the help file, to describe a single subject.  %@NL@%
  6605. %@NL@%
  6606. %@AU@% Cross-references help you navigate through  a help database.%@AE@%  %@NL@%
  6607. %@NL@%
  6608. Cross-references make it possible to view information about related topics,
  6609. including header files and code examples. The help for the %@AB@%open%@AE@% function,
  6610. for example, references the %@AB@%access%@AE@% function and the ASCII header file
  6611. FCNTL.H. Cross-references can point to other contexts in the same help
  6612. database, to contexts in other help databases, or to ASCII files outside the
  6613. database.  %@NL@%
  6614. %@NL@%
  6615. Help files can have two kinds of cross-references:  %@NL@%
  6616. %@NL@%
  6617. %@NL@%
  6618.   ■   Implicit%@NL@%
  6619. %@NL@%
  6620.   ■   Explicit, or hyperlinks%@NL@%
  6621. %@NL@%
  6622. %@NL@%
  6623. %@AU@% Implicit cross-references  are coded with an ordinary .context command.%@AE@%  %@NL@%
  6624. %@NL@%
  6625. The word "open" is an implicit cross-reference throughout C 6.0 help. If you
  6626. select the word "open" anywhere in C 6.0 help, the help system displays
  6627. information on the %@AB@%open%@AE@% function. As illustrated above, the context for %@AB@%open%@AE@%
  6628. begins with an ordinary %@AB@%.context%@AE@% command. As a result, anywhere that you
  6629. select "open," the help system references this context.  %@NL@%
  6630. %@NL@%
  6631. %@AU@% Hyperlinks are explicit cross-references marked  by invisible text.%@AE@%  %@NL@%
  6632. %@NL@%
  6633. A "hyperlink" is an explicit cross-reference tied to a word or phrase at a
  6634. specific location in the help file. You create hyperlinks when you write the
  6635. help text. The hyperlink consists of a word or phrase followed by invisible
  6636. text that gives the context to which the hyperlink refers.  %@NL@%
  6637. %@NL@%
  6638. For example, to cause an instance of the word "formatting" to display help
  6639. on the %@AB@%printf%@AE@% function, you would create an explicit cross-reference from
  6640. the word "formatting" to the context "printf." Elsewhere in the file,
  6641. "formatting" has no special significance but, at that one position, it
  6642. references the help for %@AB@%printf%@AE@%.  Section 7.5.4 describes how to create
  6643. hyperlinks.  %@NL@%
  6644. %@NL@%
  6645. %@AU@% Formatting flags let you change the appearance of text.%@AE@%  %@NL@%
  6646. %@NL@%
  6647. Help text can also include formatting flags to control the appearance of the
  6648. text on the screen. Using these flags, you can make certain words appear in
  6649. various colors, inverse video, and so forth, depending on the application
  6650. displaying help and the graphics capabilities of the host computer.  %@NL@%
  6651. %@NL@%
  6652. %@NL@%
  6653. %@3@%%@CR:C6A00070004 @%%@AB@%7.1.2  Help File Formats%@AE@%%@EH@%%@NL@%
  6654. %@NL@%
  6655. You can create help files using any of three formats:  %@NL@%
  6656. %@NL@%
  6657. %@NL@%
  6658.   ■   QuickHelp format%@NL@%
  6659. %@NL@%
  6660.   ■   Rich Text Format (RTF)%@NL@%
  6661. %@NL@%
  6662.   ■   Minimally formatted ASCII%@NL@%
  6663. %@NL@%
  6664. %@NL@%
  6665. In addition, you can reference unformatted ASCII files, such as include
  6666. files, from within a help database.  %@NL@%
  6667. %@NL@%
  6668. An entire help system (such as the one supplied with Microsoft C or
  6669. QuickBASIC) can use any combination of files formatted with different format
  6670. types. With C, for example, the README.DOC information file is encoded as
  6671. minimally formatted ASCII; the help files for the PWB, C language, and
  6672. run-time library are encoded in the QuickHelp format. The database also
  6673. cross-references the header (include) files, which are unformatted ASCII
  6674. files stored outside the database.  %@NL@%
  6675. %@NL@%
  6676. %@NL@%
  6677. %@4@%%@AB@%QuickHelp%@AE@%%@EH@%%@NL@%
  6678. %@NL@%
  6679. QuickHelp format is the default and is the format into which HELPMAKE
  6680. decodes help databases. Use any text editor to create a QuickHelp-format
  6681. help text file. QuickHelp format also lends itself to a relatively easy
  6682. automated translation from other document formats.  %@NL@%
  6683. %@NL@%
  6684. QuickHelp files can contain any kind of cross-reference or formatting
  6685. attribute. Typically, you use QuickHelp format for any changes to a database
  6686. supplied by Microsoft.  %@NL@%
  6687. %@NL@%
  6688. %@NL@%
  6689. %@4@%%@AB@%RTF%@AE@%%@EH@%%@NL@%
  6690. %@NL@%
  6691. Rich Text Format (RTF) is a Microsoft word-processing format that many other
  6692. word processors also support. You can create RTF help text with any word
  6693. processor that generates RTF output. You can also use any utility program
  6694. that takes word-processor output and produces an RTF file.  %@NL@%
  6695. %@NL@%
  6696. Use RTF when you want to transfer help files from one application to another
  6697. while retaining formatting information. You can format RTF files directly
  6698. with the word-processing program; you need not edit them to insert any
  6699. special commands or tags. Like QuickHelp files, RTF files can contain
  6700. formatting attributes and cross-references.  %@NL@%
  6701. %@NL@%
  6702. %@NL@%
  6703. %@4@%%@AB@%Minimally Formatted ASCII%@AE@%%@EH@%%@NL@%
  6704. %@NL@%
  6705. Minimally formatted ASCII files simply define contexts and their topic text.
  6706. These files cannot contain screen-formatting commands or explicit
  6707. crossreferences (implicit cross-references are allowed). They are often used
  6708. to display text such as README.DOC and small help files that do not require
  6709. compression.  %@NL@%
  6710. %@NL@%
  6711. %@NL@%
  6712. %@4@%%@AB@%Unformatted ASCII%@AE@%%@EH@%%@NL@%
  6713. %@NL@%
  6714. Unformatted ASCII files are exactly what their name implies: regular ASCII
  6715. files with no special formatting commands, context definitions, or special
  6716. information. An unformatted ASCII file does not become part of the help
  6717. database. Only its name is used as the object of a cross-reference. The
  6718. standard C header (include) files are unformatted ASCII files used for
  6719. cross-references by the help system for the C run-time library. Unformatted
  6720. ASCII files are also useful for storing program examples.  %@NL@%
  6721. %@NL@%
  6722. %@NL@%
  6723. %@2@%%@CR:C6A00070005 @%%@AB@%7.2  Invoking HELPMAKE%@AE@%%@EH@%%@NL@%
  6724. %@NL@%
  6725. The HELPMAKE program can encode or decode help files, allowing you to create
  6726. new help files or modify existing ones. Encoding converts a text file to a
  6727. compressed help database. HELPMAKE can encode text files written in
  6728. QuickHelp, RTF, and minimally formatted ASCII format. Decoding converts a
  6729. help database to a text file for editing. HELPMAKE always decodes a help
  6730. database into a QuickHelp format text file.  %@NL@%
  6731. %@NL@%
  6732. Invoke HELPMAKE with the following syntax:  %@NL@%
  6733. %@NL@%
  6734. %@AS@%  HELPMAKE «options» { /En | /D } { sourcefiles }%@AE@%%@NL@%
  6735. %@NL@%
  6736. The %@AI@%options%@AE@% modify the action of HELPMAKE; they are described in Section
  6737. 7.3.  %@NL@%
  6738. %@NL@%
  6739. %@AU@% Use the /E option to encode with HELPMAKE and use the /D option to decode.%@AE@%
  6740. %@NL@%
  6741. %@NL@%
  6742. You must supply either the /E (encode) or the /D (decode) option. When
  6743. encoding (/E) to create a help database, you must use the /O option to
  6744. specify the file name of the database.  %@NL@%
  6745. %@NL@%
  6746. The %@AI@%sourcefile%@AE@% field is required. It specifies the input file for HELPMAKE.
  6747. If you use the /D (decode) option, %@AI@%sourcefile%@AE@% can be one or more help
  6748. database files (such as QC.HLP). HELPMAKE decodes the database files into a
  6749. single text file. If you use the /E (encode) option, %@AI@%sourcefile%@AE@% can be one
  6750. or more help text files (such as QC.SRC). Separate file names with a space.
  6751. Standard wild-card characters can also be used.  %@NL@%
  6752. %@NL@%
  6753. The example below invokes HELPMAKE with the /V, /E, and /O options (see
  6754. Section 7.3.1, "Options for Encoding"). HELPMAKE reads input from the text
  6755. file %@AS@% my.txt %@AE@% and writes the compressed help database in the file %@AS@% my.hlp%@AE@%.
  6756. The /E option causes maximum compression. Note that the DOS redirection
  6757. symbol (>) sends a log of HELPMAKE activity to the file %@AS@% my.log%@AE@%. You may
  6758. find it helpful to redirect the log file because, in its more verbose modes
  6759. (given by /V), HELPMAKE may generate a lengthy log.  %@NL@%
  6760. %@NL@%
  6761. %@AS@%  HELPMAKE /V /E /Omy.hlp my.txt > my.log%@AE@%%@NL@%
  6762. %@NL@%
  6763. The example below invokes HELPMAKE to decode the help database %@AS@% my.hlp %@AE@% into
  6764. the text file %@AS@% my.src%@AE@%, given with the /O option. Once again, the /V option
  6765. results in verbose output, and the output is directed to the log file %@AS@%
  6766. %@AS@%my.log%@AE@%. Section 7.3.2 describes additional options for decoding.  %@NL@%
  6767. %@NL@%
  6768. %@AS@%  HELPMAKE /V /D /Omy.src my.hlp > my.log%@AE@%%@NL@%
  6769. %@NL@%
  6770. %@NL@%
  6771. %@2@%%@CR:C6A00070006 @%%@AB@%7.3  HELPMAKE Options%@AE@%%@EH@%%@NL@%
  6772. %@NL@%
  6773. HELPMAKE accepts a number of command-line options, which are described
  6774. below. You can specify options in uppercase or lowercase letters, and
  6775. precede them with either a forward slash ( / ) or a dash (-). For example,
  6776. -L, /L, -l, and /l all represent the same option. Most options apply only to
  6777. encoding; others apply only to decoding; and a few apply to both.  %@NL@%
  6778. %@NL@%
  6779. %@NL@%
  6780. %@3@%%@CR:C6A00070007 @%%@AB@%7.3.1  Options for Encoding%@AE@%%@EH@%%@NL@%
  6781. %@NL@%
  6782. When you encode a file─that is, when you build a help database─you must
  6783. specify the /E option. In addition, you can supply various other options
  6784. that control the way HELPMAKE works. All the options that apply when
  6785. encoding are listed below:  %@NL@%
  6786. %@NL@%
  6787. %@AB@%Option%@AE@%                            %@AB@%Action%@AE@%
  6788. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6789. /A%@AI@%c%@AE@%                               Specifies %@AI@%c%@AE@% as an application-specific 
  6790.                                   control character for the help database 
  6791.                                   file. The character marks a line that 
  6792.                                   contains special information for 
  6793.                                   internal use by the application. For 
  6794.                                   example, QuickC uses the colon (%@AB@%:%@AE@%).
  6795.  
  6796. /C                                Indicates that the context strings for 
  6797.                                   this help file are case sensitive. At 
  6798.                                   run time, all searches for help topics 
  6799.                                   are case sensitive if the help database 
  6800.                                   was built with the /C option in effect.
  6801.  
  6802. /E«%@AI@%n%@AE@%»                             Creates (encodes) a help database from a
  6803.                                   specified text file. The optional %@AI@%n%@AE@% 
  6804.                                   indicates the amount of compression to 
  6805.                                   take place. If %@AI@%n%@AE@% is omitted, HELPMAKE 
  6806.                                   compresses the file as much as possible,
  6807.                                   thereby reducing the size of the file by
  6808.                                   about 50%. The more compression 
  6809.                                   requested, the longer HELPMAKE takes to 
  6810.                                   create a database file. The value of %@AI@%n%@AE@% 
  6811.                                   is a number in the range 0 - 15. It is 
  6812.                                   the sum of successive powers of 2 
  6813.                                   representing various compression 
  6814.                                   techniques, as listed below:
  6815.  
  6816.                                   %@AB@%Value%@AE@%       %@AB@%Technique%@AE@%
  6817. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6818.                                   0           No compression
  6819.  
  6820.                                   1           Run-length compression
  6821.  
  6822.                                   2           Key word compression
  6823.  
  6824.                                   4           Extended key word
  6825.                                               compression
  6826.  
  6827.                                   8           Huffman compression
  6828.  
  6829.                                   Add values to combine compression 
  6830.                                   techniques. For example, use /E3 to get 
  6831.                                   run-length and key word compression. 
  6832.                                   This is useful in the testing stages of 
  6833.                                   creating a help database when you need 
  6834.                                   to create the database quickly and are 
  6835.                                   not too concerned with size.
  6836.  
  6837. /H                                Displays a summary of HELPMAKE syntax 
  6838.                                   and exits.
  6839.  
  6840. /HELP                             Invokes QH.EXE, the QuickHelp utility, 
  6841.                                   for help about HELPMAKE. If QuickHelp is
  6842.                                   not available, displays the same 
  6843.                                   information as the /H option.
  6844.  
  6845. /K %@AI@%filename%@AE@%                       Optimizes key word compression by 
  6846.                                   supplying a
  6847.                                   list of characters that act as word 
  6848.                                   separators. The %@AI@%filename%@AE@% is a file 
  6849.                                   containing your list of separator 
  6850.                                   characters.
  6851.  
  6852.                                   When you select key word compression, 
  6853.                                   HELPMAKE scans the help file to identify
  6854.                                   "key words." A key word is any word that
  6855.                                   occurs often enough to justify replacing
  6856.                                   it with a shorter character sequence. 
  6857.                                   HELPMAKE normally uses the following 
  6858.                                   characters as word separators:
  6859.  
  6860.                                   ■ All characters from 0-32 (including 
  6861.                                   the space)
  6862.  
  6863.                                   ■ !"#&'( )*+'-, /:;<=>?@[\]^_`{|}~
  6864.  
  6865.                                   ■ 127
  6866.  
  6867.                                   When performing key word compression, 
  6868.                                   HELPMAKE treats as a word any series of 
  6869.                                   characters not appearing in the 
  6870.                                   separator list.
  6871.  
  6872.                                   Depending on the content of your help 
  6873.                                   file, you may be able to improve key 
  6874.                                   word compression by using the /K option 
  6875.                                   to specify a different list of separator
  6876.                                   characters. For instance, the default 
  6877.                                   separator list contains the number sign 
  6878.                                   (#). If your help file contains %@AB@%#include%@AE@%
  6879.                                   directives, HELPMAKE normally treats %@AB@%%@AE@%
  6880.                                   %@AB@%#include%@AE@% as the word %@AB@%include%@AE@% without a 
  6881.                                   number sign. To cause HELPMAKE to treat %@AB@%%@AE@%
  6882.                                   %@AB@%#include%@AE@% as a word, you could specify 
  6883.                                   the following separator list:
  6884.  
  6885.                                   %@AS@%                     %@AE@%
  6886.                                   %@AS@%!"&'()*+'-,/:;<=>?@[\]^_`{|}~%@AE@%
  6887.  
  6888.                                   The list above does not include the 
  6889.                                   number sign. HELPMAKE always treats 
  6890.                                   characters in the range
  6891.                                   0-32 as separators, so you do not need 
  6892.                                   to include them. Your list must include 
  6893.                                   all the other characters you want 
  6894.                                   HELPMAKE to use as separators, including
  6895.                                   the space.
  6896.  
  6897. /L                                Locks the generated file so that it 
  6898.                                   cannot be decoded by HELPMAKE at a later
  6899.                                   time.
  6900.  
  6901. /O%@AI@%destfile%@AE@%                        Specifies %@AI@%destfile%@AE@% as the name of the 
  6902.                                   help database.
  6903.  
  6904. /S%@AI@%n%@AE@%                               Specifies the type of input file, 
  6905.                                   according to the following %@AI@%n%@AE@% values:
  6906.  
  6907.                                   %@AB@%Option%@AE@%      %@AB@%File%@AE@% %@AB@%Type%@AE@%
  6908. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6909.                                   /S1         Rich Text Format (RTF)
  6910.  
  6911.                                   /S2         QuickHelp (default)
  6912.  
  6913.                                   /S3         Minimally formatted ASCII
  6914.  
  6915. /T                                Translates dot commands into internal 
  6916.                                   format. If your help file contains dot 
  6917.                                   commands other than %@AB@%.context%@AE@%, you should
  6918.                                   supply this option when encoding it. Dot
  6919.                                   commands are described in Section 7.6.1,
  6920.                                   "QuickHelp Format," and in later 
  6921.                                   sections.
  6922.  
  6923. /V«%@AI@%n%@AE@%»                             Indicates the verbosity of diagnostic 
  6924.                                   and informational output, depending on 
  6925.                                   the value of %@AI@%n%@AE@%. Increasing the value 
  6926.                                   adds more information to the output. If 
  6927.                                   you omit this option or specify only /V,
  6928.                                   HELPMAKE gives you its most verbose 
  6929.                                   output. The possible values of %@AI@%n%@AE@% are 
  6930.                                   listed below:
  6931.  
  6932.                                   %@AB@%Option%@AE@%      %@AB@%Effect%@AE@%
  6933. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6934.                                   /V          Maximum diagnostic output
  6935.  
  6936.                                   /V0         No diagnostic output and no 
  6937.                                               banner
  6938.  
  6939.                                   /V1         Prints only HELPMAKE banner 
  6940.                                               (default)
  6941.  
  6942.                                   /V2         Prints pass names
  6943.  
  6944.                                   /V3         Prints contexts on first 
  6945.                                               pass
  6946.  
  6947.                                   /V4         Prints contexts on each pass
  6948.  
  6949.                                   /V5         Prints any intermediate 
  6950.                                               steps within each pass
  6951.  
  6952.                                   /V6         Prints statistics on help 
  6953.                                               file and compression
  6954.  
  6955. /W%@AI@%width%@AE@%                           Indicates the fixed width of the 
  6956.                                   resulting help text in number of 
  6957.                                   characters. The values of %@AI@%width%@AE@% can 
  6958.                                   range from 11 to 255. If the /W option 
  6959.                                   is omitted, the default is 76. When 
  6960.                                   encoding RTF source (/S1), HELPMAKE 
  6961.                                   automatically formats the text to %@AI@%width%@AE@%.
  6962.                                   When encoding QuickHelp (/S2) or 
  6963.                                   minimally formatted ASCII (/S3) files, 
  6964.                                   HELPMAKE truncates lines to this width.
  6965.  
  6966. %@NL@%
  6967. %@3@%%@CR:C6A00070008 @%%@AB@%7.3.2  Options for Decoding%@AE@%%@EH@%%@NL@%
  6968. %@NL@%
  6969. To decode a help database into QuickHelp files, you must use the /D option.
  6970. In addition, HELPMAKE accepts other options to control the decoding process.
  6971. The list below shows all the options that are valid when decoding:  %@NL@%
  6972. %@NL@%
  6973. %@AB@%Option%@AE@%                            %@AB@%Action%@AE@%
  6974. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6975. /D«%@AI@%letter%@AE@%»                        Decodes the input file into its original
  6976.                                   text or component parts. If a 
  6977.                                   destination file is not specified with 
  6978.                                   the /O option, the help file is decoded 
  6979.                                   to %@AB@%stdout%@AE@%. HELPMAKE decodes the file 
  6980.                                   differently depending on the letter 
  6981.                                   specified:
  6982.  
  6983.                                   %@AB@%Letter%@AE@%      %@AB@%Effect%@AE@%
  6984. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6985.                                   /D          "Decode." Fully decodes the 
  6986.                                               help database, leaving all 
  6987.                                               cross-references and 
  6988.                                               formatting information 
  6989.                                               intact.
  6990.  
  6991.                                   /DS         "Decode split." Splits the 
  6992.                                               concatenated, compressed 
  6993.                                               help database into its 
  6994.                                               components using their 
  6995.                                               original names. If the 
  6996.                                               database was created without
  6997.                                               concatenation (the default),
  6998.                                               HELPMAKE simply copies it to
  6999.                                               a file with its original 
  7000.                                               name. No decompression 
  7001.                                               occurs.
  7002.  
  7003.                                   /DU         "Decode unformatted." 
  7004.                                               Decompresses the database 
  7005.                                               and removes all screen 
  7006.                                               formatting and 
  7007.                                               cross-references. The output
  7008.                                               can still be used later for 
  7009.                                               input and recompression, but
  7010.                                               all screen formatting and 
  7011.                                               cross-references are lost.
  7012.  
  7013. /H                                Displays a summary of HELPMAKE syntax 
  7014.                                   and exits without encoding or decoding 
  7015.                                   any files.
  7016.  
  7017. /HELP                             Invokes QH.EXE, the QuickHelp utility, 
  7018.                                   for information about HELPMAKE. If 
  7019.                                   QuickHelp is not available, displays the
  7020.                                   same information as the /H option.
  7021.  
  7022. /O%@AI@%destfile%@AE@%                        Specifies %@AI@%destfile%@AE@% for the decoded 
  7023.                                   output from HELPMAKE. If %@AI@%destfile%@AE@% is 
  7024.                                   omitted, the help database is decoded to
  7025.                                   %@AB@%stdout%@AE@%. HELPMAKE always decodes help 
  7026.                                   database files into QuickHelp format.
  7027.  
  7028. /T                                Translates dot commands from internal 
  7029.                                   format into dot-command format. You 
  7030.                                   should always supply this option when 
  7031.                                   decoding a help database that contains 
  7032.                                   dot commands other than %@AB@%.context%@AE@%.
  7033.  
  7034. /V«%@AI@%n%@AE@%»                             Indicates the verbosity of diagnostic 
  7035.                                   and informational output depending on 
  7036.                                   the value of %@AI@%n%@AE@%. The possible values are 
  7037.                                   listed below. If you omit this option or
  7038.                                   specify only /V, HELPMAKE gives you its 
  7039.                                   most verbose output.
  7040.  
  7041.                                   %@AB@%Option%@AE@%      %@AB@%Effect%@AE@%
  7042. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7043.                                   /V          Maximum diagnostic output
  7044.  
  7045.                                   /V0         No diagnostic output and no 
  7046.                                               banner
  7047.  
  7048.                                   /V1         Prints only the HELPMAKE 
  7049.                                               banner
  7050.  
  7051.                                   /V2         Prints pass names
  7052.  
  7053.                                   /V3         Prints contexts on first 
  7054.                                               pass
  7055.  
  7056. %@NL@%
  7057. %@2@%%@CR:C6A00070009 @%%@AB@%7.4  Creating a Help Database%@AE@%%@EH@%%@NL@%
  7058. %@NL@%
  7059. You can create a Microsoft-compatible help database by either of two
  7060. methods.  %@NL@%
  7061. %@NL@%
  7062. The first method is to decompress an existing help database, modify the
  7063. resulting help text file, and recompress the help text file to form a new
  7064. database.  %@NL@%
  7065. %@NL@%
  7066. The second and simpler method is to append a new help database to an
  7067. existing help database. This method involves the following steps:  %@NL@%
  7068. %@NL@%
  7069. %@NL@%
  7070.   1.  Create a help text file in QuickHelp format, RTF, or minimally
  7071.       formatted ASCII.%@NL@%
  7072. %@NL@%
  7073.   2.  Use HELPMAKE to create a help database file. The example below invokes
  7074.       HELPMAKE, using SAMPLE.TXT as the input file and producing a help
  7075.       database file named %@AS@% sample.hlp%@AE@%:
  7076. %@NL@%
  7077. %@AS@%      HELPMAKE /V /E /Osample.hlp sample.txt > sample.log%@AE@%%@NL@%
  7078. %@NL@%
  7079. %@NL@%
  7080.   3.  Make a backup copy of the existing database file (for safety's sake).%@NL@%
  7081. %@NL@%
  7082.   4.  Append the new help database file to the existing help database. The
  7083.       example below concatenates the new database %@AS@% sample.hlp %@AE@% onto the end
  7084.       of the CLANG.HLP database:
  7085. %@NL@%
  7086. %@AS@%      COPY clang.hlp /b + sample.hlp /b%@AE@%%@NL@%
  7087. %@NL@%
  7088. %@NL@%
  7089.   5.  Test the database. The %@AS@% sample.hlp %@AE@% database contains the context %@AS@%
  7090. %@AS@%      sample%@AE@%. If you type the word "sample" in the PWB and request help on
  7091.       it, the help window displays the text associated with the context %@AS@%
  7092. %@AS@%      sample%@AE@%.%@NL@%
  7093. %@NL@%
  7094. %@NL@%
  7095. %@NL@%
  7096. %@2@%%@CR:C6A00070010 @%%@AB@%7.5  Help Text Conventions%@AE@%%@EH@%%@NL@%
  7097. %@NL@%
  7098. Microsoft help databases have a common structure and follow certain
  7099. organizational conventions. You should follow the same conventions to create
  7100. Microsoft-compatible help files.  %@NL@%
  7101. %@NL@%
  7102. %@NL@%
  7103. %@3@%%@CR:C6A00070011 @%%@AB@%7.5.1  Structure of the Help Text File%@AE@%%@EH@%%@NL@%
  7104. %@NL@%
  7105. The help-retrieval capability that is built into Microsoft products is
  7106. simply a data-retrieval tool. It imposes no restrictions on the content and
  7107. format of the help text. The HELPMAKE utility and the display routines built
  7108. into Microsoft language environments, however, make certain assumptions
  7109. about the format of help text. This section provides some guidelines for
  7110. creating help text files compatible with those assumptions.  %@NL@%
  7111. %@NL@%
  7112. In all three help text formats, the help text source file is a sequence of
  7113. topics, each preceded by one or more unique context definitions. The
  7114. following list specifies the various formats and the corresponding context
  7115. definition statements:  %@NL@%
  7116. %@NL@%
  7117. %@AB@%Format %@AE@%                           %@AB@%Context Definition%@AE@%
  7118. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7119. QuickHelp                         %@AB@%.context %@AE@%%@AI@%context%@AE@%
  7120.  
  7121. RTF                               \ par %@AI@%>>context%@AE@% \ par
  7122.  
  7123. Minimally formatted               %@AI@%>>context%@AE@%
  7124.  
  7125. ASCII                             (none)
  7126.  
  7127. In QuickHelp format, each topic begins with one or more %@AB@%.context%@AE@% statements
  7128. that define the context strings that map to the topic text. Subsequent lines
  7129. up to the next %@AB@%.context%@AE@% statement constitute the topic text.  %@NL@%
  7130. %@NL@%
  7131. In RTF format, each context definition must be in a paragraph of its own
  7132. (denoted by \ par), beginning with the help delimiter (>>). Subsequent
  7133. paragraphs up to the next context definition constitute the topic text.  %@NL@%
  7134. %@NL@%
  7135. In minimally formatted ASCII, each context definition must be on a separate
  7136. line, and each must begin with the help delimiter (>>). As in RTF and
  7137. QuickHelp files, subsequent lines up to the next context definition
  7138. constitute the topic text.  %@NL@%
  7139. %@NL@%
  7140. See Section 7.6, "Using Help Database Formats," for detailed information
  7141. about these three formats.  %@NL@%
  7142. %@NL@%
  7143. %@NL@%
  7144. %@3@%%@CR:C6A00070012 @%%@AB@%7.5.2  Local Contexts%@AE@%%@EH@%%@NL@%
  7145. %@NL@%
  7146. Context strings that begin with an "at" sign (@) are defined as "local" and
  7147. have no implicit cross-references. They are used in cross-references instead
  7148. of the context string that otherwise is generated.%@CR:C6A00070013 @%  %@NL@%
  7149. %@NL@%
  7150. When you use a local context, HELPMAKE does not generate a global context
  7151. string (a context string that is known throughout the help file). Instead,
  7152. it embeds an encoded cross-reference that has meaning only within the
  7153. current context. For example,  %@NL@%
  7154. %@NL@%
  7155. %@AS@%  .context normal
  7156. %@AS@%  This is a normal topic, accessible by the context string "normal."
  7157. %@AS@%  [button\v@local\v] is a cross-reference to the following topic.
  7158. %@AS@%  
  7159. %@AS@%  .context @local
  7160. %@AS@%  
  7161. %@AS@%  This topic can be reached only if the user browses
  7162. %@AS@%  sequentially through the file or uses the cross-reference
  7163. %@AS@%  in the previous topic.%@AE@%%@NL@%
  7164. %@NL@%
  7165. In the example above, the text %@AS@% [button\v@local\v] %@AE@% defines %@AS@% local %@AE@% as a
  7166. local context. If the user selects the text %@AS@% [button] %@AE@% or scrolls through
  7167. the file, the help system displays the topic text that follows the context
  7168. definition for %@AS@% local%@AE@%. Because %@AS@% local %@AE@% is defined with the "at" sign (@), it
  7169. can be accessed only by a hyperlink within the help file or by sequentially
  7170. browsing through the file. Making a context local saves file space and
  7171. speeds access.  %@NL@%
  7172. %@NL@%
  7173. %@NL@%
  7174. %@3@%%@CR:C6A00070014 @%%@AB@%7.5.3  Context Prefixes%@AE@%%@EH@%%@NL@%
  7175. %@NL@%
  7176. Microsoft help databases use several context prefixes. A "context prefix" is
  7177. a single letter followed by a period. It appears before a context string
  7178. that has a predefined meaning. If you decode a Microsoft help database, many
  7179. of these contexts may appear in the resulting text file.  %@NL@%
  7180. %@NL@%
  7181. %@AU@% Most context prefixes are internal. %@AE@%  %@NL@%
  7182. %@NL@%
  7183. Except for the h. prefix, which is described below, context prefixes are
  7184. internal. You do not need to add them in help files that you write.  %@NL@%
  7185. %@NL@%
  7186. You can use the h. prefix to identify standard help-file contexts. For
  7187. instance, h.default identifies the default help screen: the screen that
  7188. normally appears when you select "top-level" help. Table 7.1 lists the
  7189. standard h. contexts.  %@NL@%
  7190. %@NL@%
  7191. %@AB@%Table 7.1  %@AB@%Standard h. Contexts%@AE@%%@AE@%
  7192.  
  7193. %@TH:  43  2399 02 34 42 @%
  7194. Context                           Description
  7195. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7196. h.contents                        The table of contents for the help file.
  7197.                                   You should also define the string 
  7198.                                   "contents" for direct reference to this 
  7199.                                   context.
  7200.  
  7201. h.default                         The default help screen, typically 
  7202.                                   displayed when the user presses SHIFT+F1
  7203.                                   at the "top level" in most applications.
  7204.                                   The contents are generally devoted to 
  7205.                                   information about using help.
  7206.  
  7207. h.index                           The index for the help file.  You can 
  7208.                                   also define the string "index" for 
  7209.                                   direct reference to this context.
  7210.  
  7211. h.notfound                        The help text that is displayed when the
  7212.                                   help system cannot find information 
  7213.                                   about the requested context. The text 
  7214.                                   could be an index of contexts, a topical
  7215.                                   list, or general information about using
  7216.                                   help.
  7217.  
  7218. h.pg#                             A specific page within the help file. 
  7219.                                   This is used in response to a "go to 
  7220.                                   page #" request.
  7221.  
  7222. h.pg$                             The help text that is logically last in 
  7223.                                   the file. This is used by some 
  7224.                                   applications in response to a "go to the
  7225.                                   end" request made within the help window.
  7226.  
  7227. h.pg1                             The help text that is logically first in
  7228.                                   the file. This is used by some 
  7229.                                   applications in response to a "go to the
  7230.                                   beginning" request made within the help 
  7231.                                   window.
  7232.  
  7233. h.title                           The title of the help database.
  7234.  
  7235. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7236.  
  7237. %@TE:  43  2399 02 34 42 @%
  7238.  
  7239. The context prefixes in Table 7.2 are internal to Microsoft products. They
  7240. appear in decompressed databases, but you do not need to use them.  %@NL@%
  7241. %@NL@%
  7242. %@AB@%Table 7.2  %@AB@%Microsoft Product Context Prefixes%@AE@%%@AE@%
  7243.  
  7244. %@TH:  28  1705 02 34 42 @%
  7245. Prefix                            Purpose
  7246. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7247. d.                                Dialog box. Each dialog box is assigned 
  7248.                                   a number. Its help context string is d. 
  7249.                                   followed by the number (for example, %@AS@% %@AE@%
  7250.                                   %@AS@%d.12%@AE@%).
  7251.  
  7252. e.                                Error number. If a product supports the 
  7253.                                   error-numbering scheme used by Microsoft
  7254.                                   languages, it displays help for each 
  7255.                                   error using this prefix. For example, 
  7256.                                   the context %@AS@% e.c1234 %@AE@% refers to the C 
  7257.                                   compiler error message number C1234.
  7258.  
  7259. m.                                Menu item. Contexts that relate to 
  7260.                                   product menu items are defined by their 
  7261.                                   accelerator keys. For example, the Exit 
  7262.                                   selection on the FILE menu item is 
  7263.                                   accessed by ALT+F X and is referenced in
  7264.                                   help by %@AS@% m.f.x%@AE@%.
  7265.  
  7266. n.                                Message number. Each message box is 
  7267.                                   assigned a number. Its help context 
  7268.                                   string is n. plus the number (for 
  7269.                                   example, %@AS@% n.5 %@AE@%).
  7270.  
  7271. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7272.  
  7273. %@TE:  28  1705 02 34 42 @%
  7274.  
  7275. %@NL@%
  7276. %@3@%%@CR:C6A00070015 @%%@AB@%7.5.4  Hyperlinks%@AE@%%@EH@%%@NL@%
  7277. %@NL@%
  7278. Explicit cross-references, or hyperlinks, in the help text file are marked
  7279. with invisible text. A hyperlink comprises a word or phrase followed by
  7280. invisible text that gives the context to which the hyperlink refers.  %@NL@%
  7281. %@NL@%
  7282. The keystroke that activates the hyperlink depends on the application.
  7283. Consult the documentation for each product to find the specific keystroke
  7284. needed.  %@NL@%
  7285. %@NL@%
  7286. When the user activates the hyperlink, the help system displays the topic
  7287. named by the invisible text. The invisible cross-reference text is formatted
  7288. as one of the following:  %@NL@%
  7289. %@NL@%
  7290. %@AB@%Hyperlink Text%@AE@%                    %@AB@%Action%@AE@%
  7291. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7292. %@AI@%contextstring%@AE@%                     Causes the help topic associated with %@AI@%%@AE@%
  7293.                                   %@AI@%contextstring%@AE@% to be displayed. For 
  7294.                                   example, %@AS@% exeformat %@AE@% results in the 
  7295.                                   display of the help topic associated 
  7296.                                   with the context %@AS@% exeformat%@AE@%.
  7297.  
  7298. %@AI@%filename%@AE@%!                         Treats %@AI@%filename%@AE@% as a single topic to be 
  7299.                                   displayed. For example, %@AS@% %@AE@%
  7300.                                   %@AS@%$INCLUDE:stdio.h! %@AE@% searches the
  7301.                                   INCLUDE environment variable for file 
  7302.                                   STDIO.H and displays it as a single help
  7303.                                   topic.
  7304.  
  7305. %@AI@%filename%@AE@%!%@AI@%contextstring%@AE@%            Works the same way as %@AI@%contextstring%@AE@% 
  7306.                                   above, except that only the help file %@AI@%%@AE@%
  7307.                                   %@AI@%filename%@AE@% is searched for the context. If
  7308.                                   the file is not already open, the help 
  7309.                                   system finds it (by searching either the
  7310.                                   current path or an explicit environment 
  7311.                                   variable) and opens it. For example, %@AS@% %@AE@%
  7312.                                   %@AS@%$BIN:readme.doc!patches %@AE@% searches for %@AS@% %@AE@%
  7313.                                   %@AS@%readme.doc %@AE@% in the BIN environment 
  7314.                                   variable and displays the topic 
  7315.                                   associated with %@AS@% patches%@AE@%.
  7316.  
  7317. In the following example, the word %@AS@% Example %@AE@% is a hyperlink:  %@NL@%
  7318. %@NL@%
  7319. %@AS@%  \bSee also:\p   \uExample\p\vopen.ex\v%@AE@%%@NL@%
  7320. %@NL@%
  7321. The hyperlink refers to %@AS@% open.ex%@AE@%. If you select any of the letters of %@AS@%
  7322. %@AS@%Example%@AE@%, the help system displays the topic whose context is %@AS@% open.ex%@AE@%. On
  7323. the screen, this line appears as follows:  %@NL@%
  7324. %@NL@%
  7325. %@AS@%  See also:   Example%@AE@%%@NL@%
  7326. %@NL@%
  7327. An application might display %@AS@% See also: %@AE@% and %@AS@% Example %@AE@% in different colors
  7328. or character types, depending on such factors as your default color
  7329. selection and type of monitor.  %@NL@%
  7330. %@NL@%
  7331. When a hyperlink needs to cross-reference more than one word, you must use
  7332. an anchor, as in the following example:  %@NL@%
  7333. %@NL@%
  7334. %@AS@%  \bSee also:\p   \uExample\p\vprintf.ex\v, fprintf, scanf, sprintf,
  7335. %@AS@%  vfprintf, vprintf, vsprintf
  7336. %@AS@%              \aformatting table\vprintf.table\v%@AE@%%@NL@%
  7337. %@NL@%
  7338. This part of the example is an anchored hyperlink:  %@NL@%
  7339. %@NL@%
  7340. %@AS@%  \aformatting table\vprintf.table\v%@AE@%%@NL@%
  7341. %@NL@%
  7342. %@AU@% Anchored hyperlinks must fit on a single line.%@AE@%  %@NL@%
  7343. %@NL@%
  7344. The \ a flag creates an anchor for the cross-reference. In the example, the
  7345. phrase following the \ a flag (%@AS@%formatting table%@AE@%) is the hyperlink. It refers
  7346. to the context %@AS@% printf.table%@AE@%. The first \v flag marks both the end of the
  7347. hyperlink and the beginning of the invisible text. The name %@AS@% printf.table %@AE@%
  7348. is invisible; it does not appear on the screen when the help is displayed.
  7349. The second \v flag ends the invisible text.  %@NL@%
  7350. %@NL@%
  7351. %@NL@%
  7352. %@2@%%@CR:C6A00070016 @%%@AB@%7.6  Using Help Database Formats%@AE@%%@EH@%%@NL@%
  7353. %@NL@%
  7354. The text format of the database can be any of three types. The list below
  7355. briefly describes these types. Sections 7.6.1-7.6.3 describe the formatting
  7356. types in detail.  %@NL@%
  7357. %@NL@%
  7358. An entire help system (such as the one supplied with the Professional
  7359. Development System or QuickC) can use any combination of files formatted
  7360. with different format types. With C, for example, the README.DOC information
  7361. file is encoded as minimally formatted ASCII; and the help files for the C
  7362. language and run-time library are encoded in the QuickHelp format. The
  7363. database also cross-references the header (include) files, which are
  7364. unformatted ASCII files stored outside the database.  %@NL@%
  7365. %@NL@%
  7366. %@AB@%Type%@AE@%                              %@AB@%Characteristics%@AE@%
  7367. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7368. QuickHelp                         Uses dot commands and embedded 
  7369.                                   formatting characters (the default 
  7370.                                   formatting type expected by HELPMAKE); 
  7371.                                   supports highlighting, color, and 
  7372.                                   cross-references. This format must be 
  7373.                                   compressed before using.
  7374.  
  7375. Minimally formatted ASCII         Uses a help delimiter (>>) to define 
  7376.                                   help contexts; does not support 
  7377.                                   highlighting, color, or crossreferences.
  7378.                                   This format can be compressed, but 
  7379.                                   compression is not required.
  7380.  
  7381. RTF                               Uses a subset of standard RTF; supports 
  7382.                                   highlighting, color, and 
  7383.                                   cross-references; supports dot commands.
  7384.                                   This format must be compressed before 
  7385.                                   using.
  7386.  
  7387. %@NL@%
  7388. %@3@%%@CR:C6A00070017 @%%@AB@%7.6.1  QuickHelp Format%@AE@%%@EH@%%@NL@%
  7389. %@NL@%
  7390. The QuickHelp format uses a dot command and embedded formatting flags to
  7391. convey information to HELPMAKE.%@CR:C6A00070018 @%  %@NL@%
  7392. %@NL@%
  7393. %@NL@%
  7394. %@4@%%@AB@%QuickHelp Dot Commands%@AE@%%@EH@%%@NL@%
  7395. %@NL@%
  7396. QuickHelp supports a number of dot commands, which identify topics and
  7397. convey other topic-related information to the help system. If your help file
  7398. contains dot commands other than %@AB@%.context%@AE@%, you must supply the /T option
  7399. when encoding and decoding with HELPMAKE.  %@NL@%
  7400. %@NL@%
  7401. %@AU@% You can define more than one context for a single topic.%@AE@%  %@NL@%
  7402. %@NL@%
  7403. The most important dot command is the %@AB@%.context%@AE@% command. Every topic in a
  7404. QuickHelp file begins with one or more %@AB@%.context%@AE@% commands. Each %@AB@%.context%@AE@%
  7405. command defines a context string for the topic text. You can define more
  7406. than one context for a single topic, as long as you do not place any topic
  7407. text between them.%@CR:C6A00070019 @%  %@NL@%
  7408. %@NL@%
  7409. Typical dot commands are shown below. The first defines a context for the %@AB@%
  7410. %@AB@%#include%@AE@% C preprocessor directive. The second set illustrates multiple
  7411. contexts for one block of topic text. In this case, the same topic text
  7412. explains all of the string-to-number conversion routines in C.  %@NL@%
  7413. %@NL@%
  7414. %@AS@%  .context #include
  7415. %@AS@%         .
  7416. %@AS@%         .description of #include goes here
  7417. %@AS@%         .
  7418. %@AS@%  .context strtod
  7419. %@AS@%  .context strtol
  7420. %@AS@%  .context strtoul
  7421. %@AS@%         .
  7422. %@AS@%         . description of string-to-number functions goes here
  7423. %@AS@%         .%@AE@%%@NL@%
  7424. %@NL@%
  7425. The QuickHelp format supports several other dot commands. Table 7.3 lists
  7426. all of the dot commands available in QuickHelp format.  %@NL@%
  7427. %@NL@%
  7428. %@AB@%Table 7.3  %@AB@%QuickHelp Dot Commands%@AE@%%@AE@%
  7429.  
  7430. %@TH: 100  6368 02 34 42 @%
  7431. %@AB@%Command%@AE@%                           %@AB@%Action%@AE@%
  7432. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7433. %@AB@%.category%@AE@% %@AI@%string%@AE@%                  Lists the category in which the current 
  7434.                                   topic appears and its position in the 
  7435.                                   list of topics. The category name is 
  7436.                                   used by the QuickHelp Topic command, 
  7437.                                   which brings up the list of topics to 
  7438.                                   which the current topic belongs. Some 
  7439.                                   applications, such as the PWB, use this 
  7440.                                   name as a pointer to the applicable 
  7441.                                   table of contents.
  7442.  
  7443. %@AB@%.command%@AE@%                          Indicates that the topic text is not a 
  7444.                                   displayable help topic. Use this command
  7445.                                   to hide hyperlink topics and other 
  7446.                                   internal information. Hyperlink topics 
  7447.                                   are described in Section 7.5.5, 
  7448.                                   "Hyperlink Commands."
  7449.  
  7450. %@AB@%.comment%@AE@% %@AI@%string%@AE@%                   The %@AI@%string%@AE@% is a comment that appears 
  7451.                                   only in the help source file. Comments 
  7452.                                   are especially useful for documenting 
  7453.                                   the purpose of cross-references.
  7454.  
  7455.                                   Because comments are not inserted in the
  7456.                                   help database, they are not restored 
  7457.                                   when you decompress a help file.
  7458.  
  7459. %@AB@%.context%@AE@% %@AI@%string%@AE@%                   The %@AI@%string%@AE@% introduces a topic.
  7460.  
  7461.  
  7462.  
  7463. %@AB@%.end%@AE@%                              Ends a paste section. See the %@AB@%.paste%@AE@% 
  7464.                                   command below.
  7465.  
  7466. %@AB@%.freeze%@AE@% %@AI@%numlines%@AE@%                  Indicates that the first %@AI@%numlines%@AE@% lines 
  7467.                                   should be frozen as the top line of the 
  7468.                                   help screen. This is normally used to 
  7469.                                   freeze a row of cross-reference buttons 
  7470.                                   at the top of a help topic that might be
  7471.                                   scrolled.%@CR:C6A00070020 @%
  7472.  
  7473. %@AB@%.length%@AE@% %@AI@%topiclength%@AE@%               Indicates the default window size, in %@AI@%%@AE@%
  7474.                                   %@AI@%topiclength%@AE@% lines, of the topic about to
  7475.                                   be displayed. This command is always the
  7476.                                   first line in the topic if present.
  7477.  
  7478. %@AB@%.list%@AE@%                             Indicates that the current topic 
  7479.                                   contains a list of topics. QuickHelp 
  7480.                                   displays a highlighted line; you can 
  7481.                                   choose 
  7482.                                   a topic by moving the highlighted line 
  7483.                                   over the desired topic and pressing %@AB@%%@AE@%
  7484.                                   %@AB@%ENTER%@AE@%. Help searches for the first word 
  7485.                                   of the line.
  7486.  
  7487. %@AB@%.mark%@AE@% %@AI@%name%@AE@% «%@AI@%column%@AE@%»               Defines a mark immediately preceding the
  7488.                                   following line of text. This command can
  7489.                                   be used in help script commands to 
  7490.                                   indicate that the display of a 
  7491.                                   particular topic begins at the marked 
  7492.                                   line. The %@AI@%name%@AE@% identifies the mark. The 
  7493.                                   optional %@AI@%column%@AE@% value is an integer that
  7494.                                   indicates a column location within the 
  7495.                                   specified line.
  7496.  
  7497. %@AB@%.next%@AE@% %@AI@%context%@AE@%                     Tells the help system to look up the 
  7498.                                   next topic using %@AI@%%@AE@%
  7499.                                   %@AI@%context%@AE@% instead of the next topic's name.
  7500.                                   You can use this command to skip large 
  7501.                                   blocks of %@AB@%.command%@AE@% or %@AB@%.popup%@AE@% topics.
  7502.  
  7503. %@AB@%.previous%@AE@% %@AI@%context%@AE@%                 Tells the help system to look up the 
  7504.                                   previous topic using %@AI@%context%@AE@% instead of 
  7505.                                   the previous topic's name. You can use 
  7506.                                   this command to skip large blocks of %@AB@%%@AE@%
  7507.                                   %@AB@%.command%@AE@% or %@AB@%.popup%@AE@% topics.
  7508.  
  7509. %@AB@%.paste%@AE@% %@AI@%pastename%@AE@%                  Begins a paste section. The %@AI@%pastename%@AE@% 
  7510.                                   appears in the QuickHelp Paste menu.
  7511.  
  7512. %@AB@%.popup%@AE@%                            Tells the help system to display the 
  7513.                                   current topic as a popup instead of a 
  7514.                                   normal, scrollable topic.
  7515.  
  7516. %@AB@%.ref%@AE@% %@AI@%string(s)%@AE@%                    Tells the help system to display the 
  7517.                                   list of %@AI@%string%@AE@% topics in the Reference 
  7518.                                   menu. You can list as many topics as 
  7519.                                   needed; separate each additional %@AI@%string%@AE@% 
  7520.                                   with a comma.
  7521.  
  7522. %@AB@%.topic%@AE@% %@AI@%text%@AE@%                       Defines %@AI@%text%@AE@% as the name or title to be 
  7523.                                   displayed in place of the context string
  7524.                                   if the application help displays a title.
  7525.                                   This command is always the first line in
  7526.                                   the context unless you also use the %@AB@% %@AE@%
  7527.                                   %@AB@%.length%@AE@% command.%@CR:C6A00070021 @%
  7528.  
  7529. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7530.  
  7531. %@TE: 100  6368 02 34 42 @%
  7532.  
  7533. %@NL@%
  7534. %@4@%%@AB@%QuickHelp Formatting Flags%@AE@%%@EH@%%@NL@%
  7535. %@NL@%
  7536. The QuickHelp format supports a number of formatting flags that are used to
  7537. highlight parts of the help database and to mark hyperlinks in the help
  7538. text.  %@NL@%
  7539. %@NL@%
  7540. Each formatting flag consists of a backslash ( \ ) followed by a character.
  7541. Table 7.4 lists the formatting flags.  %@NL@%
  7542. %@NL@%
  7543. %@AB@%Table 7.4  %@AB@%Formatting Flags%@AE@%%@AE@%
  7544.  
  7545. %@TH:  19   773 02 34 42 @%
  7546. Formatting Flag                   Action
  7547. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7548. \a                                Anchors text for cross-references
  7549.  
  7550. \b, \B                            Turns boldface on or off
  7551.  
  7552. \i, \I                            Turns italics on or off
  7553.  
  7554. \p, \P                            Turns off all attributes
  7555.  
  7556. \u, \U                            Turns underlining on or off
  7557.  
  7558. \v, \V                            Turns invisibility on or off (hides 
  7559.                                   cross-references in text)
  7560.  
  7561. \\                                Inserts a single backslash in text
  7562.  
  7563. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7564.  
  7565. %@TE:  19   773 02 34 42 @%
  7566.  
  7567. On monochrome monitors, text labeled with the bold, italic, and underlining
  7568. attributes appears in various ways, depending on the application (for
  7569. example, high intensity and reverse video are commonly displayed). On color
  7570. monitors, these attributes are translated by the application into suitable
  7571. colors, depending on the user's default color selections.  %@NL@%
  7572. %@NL@%
  7573. The \b, \i, \u, and \v options are toggles, turning on and off their
  7574. respective attributes. You can use several of these on the same text. Use
  7575. the \p attribute to turn off all attributes. Use the \v attribute to hide
  7576. cross-references and hyperlinks in the text.  %@NL@%
  7577. %@NL@%
  7578. HELPMAKE truncates the lines in QuickHelp files to the width specified with
  7579. the /W option. (See Section 7.3.1, "Options for Encoding," for more
  7580. information.) Only visible characters count toward the character-width
  7581. limit. Lines that begin with an application-specific control character are
  7582. truncated to 255 characters regardless of the width specification. See
  7583. Section 7.3.1 for more information about application-specific control
  7584. characters.  %@NL@%
  7585. %@NL@%
  7586. In the example below, the \b flag initiates boldface text for %@AS@% Returns:%@AE@%, and
  7587. the \p flag that follows the word reverts to plain text for the remainder of
  7588. the line.  %@NL@%
  7589. %@NL@%
  7590. %@AS@%  \bReturns:\p    a handle if successful, or -1 if not.
  7591. %@AS@%              errno:  EACCES, EEXIST, EMFILE, ENOENT%@AE@%%@NL@%
  7592. %@NL@%
  7593. In the example below, \a anchors text for the hyperlink %@AS@% Example %@AE@%. The \v
  7594. flags define the cross-reference to be %@AS@% sample_prog %@AE@% and cause the text
  7595. between the flags to be invisible. Cross-references are described in the
  7596. following section.  %@NL@%
  7597. %@NL@%
  7598. %@AS@%  \aExample \vsample_prog\v%@AE@%%@NL@%
  7599. %@NL@%
  7600. %@NL@%
  7601. %@4@%%@AB@%QuickHelp Cross-References%@AE@%%@EH@%%@NL@%
  7602. %@NL@%
  7603. Help databases contain two types of cross-references: implicit
  7604. cross-references and explicit cross-references. They are described in
  7605. Section 7.1.1, "Contents of a Help File."  %@NL@%
  7606. %@NL@%
  7607. An implicit cross-reference is any word that appears both in the topic text
  7608. and as a context in the help file. For example, any time you request help on
  7609. the word "close," the help window displays help on the %@AB@%close%@AE@% function. You
  7610. don't need to code implicit cross-references in your help text files.  %@NL@%
  7611. %@NL@%
  7612. %@AU@% Insert formatting flags to mark explicit cross-references.%@AE@%  %@NL@%
  7613. %@NL@%
  7614. Explicit cross-references (hyperlinks) are words or phrases on the screen
  7615. that are associated with a context. For example, the word "Example" in the
  7616. initial help-screen area for any C function is an explicit cross-reference
  7617. to the C program example for that function. You must insert formatting flags
  7618. in your help text files to mark explicit cross-references.  %@NL@%
  7619. %@NL@%
  7620. If the hyperlink consists of a single word, you can use invisible text to
  7621. flag it in the source file. The \v formatting flag creates invisible text,
  7622. as follows:  %@NL@%
  7623. %@NL@%
  7624. %@AS@%  hyperlink\vcontext\v%@AE@%%@NL@%
  7625. %@NL@%
  7626. Specify the first \v flag immediately following the word you want to use as
  7627. the hyperlink. Following the flag, insert the context that the hyperlink
  7628. crossreferences. The second \v flag marks the end of the context; that is,
  7629. the end of the invisible text. HELPMAKE generates a cross-reference whose
  7630. context is the invisible text, and whose hyperlink is the entire word.  %@NL@%
  7631. %@NL@%
  7632. If the hyperlink consists of a phrase, rather than a single word, you must
  7633. use anchored text to create explicit cross-references. Use the \a and \v
  7634. flags to create anchored text as follows:  %@NL@%
  7635. %@NL@%
  7636. %@AS@%  \ahyperlink-words\vcontext\v%@AE@%%@NL@%
  7637. %@NL@%
  7638. The \a flag marks an anchor for the cross-reference. The text that follows
  7639. the \a flag is the hyperlink. The hyperlink must fit entirely on one line.
  7640. The first \v flag marks both the end of the hyperlink and the beginning of
  7641. the invisible text that  %@NL@%
  7642. %@NL@%
  7643. contains the cross-reference context. The second \v flag marks the end of
  7644. the invisible text.  %@NL@%
  7645. %@NL@%
  7646. The following example contains three implicit cross-references to the C
  7647. routines %@AB@%abs%@AE@%, %@AB@%cabs%@AE@%, and %@AB@%fabs%@AE@%.  %@NL@%
  7648. %@NL@%
  7649. %@AS@%  See also: abs, cabs, fabs%@AE@%%@NL@%
  7650. %@NL@%
  7651. The following example shows the encoding for an explicit cross-reference to
  7652. an example program and a function template from the help database for the C
  7653. run-time library:  %@NL@%
  7654. %@NL@%
  7655. %@AS@%  See also: Example\vopen.ex\v, Template\vopen.tm\v, close%@AE@%%@NL@%
  7656. %@NL@%
  7657. Here, the hyperlinks are %@AS@% Example %@AE@% and %@AS@% Template%@AE@%, which reference the
  7658. contexts %@AS@% open.ex %@AE@% and %@AS@% open.tm%@AE@%. The example also contains an implicit
  7659. cross-reference to the %@AB@%close%@AE@% function.  %@NL@%
  7660. %@NL@%
  7661. The following example shows the encoding for an explicit cross-reference to
  7662. an entire family of functions:  %@NL@%
  7663. %@NL@%
  7664. %@AS@%  See also: \ais... functions\vis_functions\v, atoi%@AE@%%@NL@%
  7665. %@NL@%
  7666. The cross-reference uses anchored text to associate a phrase, rather than
  7667. just a word, with a context. In this example, the hyperlink is the anchored
  7668. phrase %@AS@% is... functions%@AE@%, and it cross-references the context %@AS@% is_functions%@AE@%.
  7669. In addition, the example contains an implicit cross-reference to the %@AB@%atoi%@AE@%
  7670. routine.  %@NL@%
  7671. %@NL@%
  7672. The code below is an example in QuickHelp format that contains a single
  7673. entry:  %@NL@%
  7674. %@NL@%
  7675. %@AS@%  .context open
  7676. %@AS@%  .length 13
  7677. %@AS@%  \bInclude:\p   <fcntl.h>, <io.h>, <sys\\types.h>, <sys\\stat.h>
  7678. %@AS@%  
  7679. %@AS@%  \bPrototype:\p  int open(char *path, int flag[, int mode]);
  7680. %@AS@%            flag:  O_APPEND O_BINARY O_CREAT O_EXCL O_RDONLY
  7681. %@AS@%                   O_RDWR    O_TEXT    O_TRUNC  O_WRONLY
  7682. %@AS@%                   (can be joined by |)
  7683. %@AS@%            mode:  S_IWRITE  S_IREAD   S_IREAD | S_IWRITE%@AE@%%@NL@%
  7684. %@NL@%
  7685. %@AS@%  \bReturns:\p    a handle if successful, or -1 if not.
  7686. %@AS@%              errno:  EACCES, EEXIST, EMFILE, ENOENT
  7687. %@AS@%  
  7688. %@AS@%  \bSee also:\p  \uExample\p\vopen.ex\v, \uTemplate\p\vopen.tp\v,
  7689. %@AS@%               access, chmod, close, creat, dup, dup2, fopen, sopen, umask%@AE@%%@NL@%
  7690. %@NL@%
  7691. The%@AB@% .length %@AE@%command near the beginning of the example specifies the size of
  7692. the initial window for the help text. Here, the initial window displays 13
  7693. lines.  %@NL@%
  7694. %@NL@%
  7695. The manifest constants (such as %@AB@%O_WRONLY%@AE@% and %@AB@%EEXIST%@AE@%), the C keywords (such
  7696. as %@AB@%int%@AE@% and %@AB@%char%@AE@%), and the other functions (such as %@AB@%sopen%@AE@% and %@AB@%access%@AE@%) are
  7697. implicit cross-references. The words %@AS@% Example %@AE@% and %@AS@% Template %@AE@% are explicit
  7698. cross-references to the example %@AS@% open.ex %@AE@% and to the %@AB@%open%@AE@% template %@AS@% open.tp%@AE@%,
  7699. respectively. Note the use of double backslashes in the include file names.
  7700. %@NL@%
  7701. %@NL@%
  7702. %@NL@%
  7703. %@3@%%@CR:C6A00070022 @%%@AB@%7.6.2  Minimally Formatted ASCII Format%@AE@%%@EH@%%@NL@%
  7704. %@NL@%
  7705. A minimally formatted ASCII text file comprises a sequence of topics, each
  7706. preceded by one or more unique context definitions. Each context definition
  7707. must be on a separate line beginning with a help delimiter (>>). Subsequent
  7708. lines up to the next context definition constitute the topic text.  %@NL@%
  7709. %@NL@%
  7710. %@AU@% Minimally formatted ASCII files cannot contain highlighting.%@AE@%  %@NL@%
  7711. %@NL@%
  7712. Minimally formatted ASCII files can be used in two ways. You can compress
  7713. the file with HELPMAKE, creating a help database, or an application can
  7714. access the uncompressed file directly. Uncompressed files are somewhat
  7715. larger and slower to search, however. Minimally formatted ASCII files are of
  7716. fixed width, and they cannot contain highlighting (or other nondefault
  7717. attributes) or cross-references.  %@NL@%
  7718. %@NL@%
  7719. The following example, coded in minimally formatted ASCII, shows the same
  7720. text as the QuickHelp example in the previous section. The first line of the
  7721. example defines %@AS@% open %@AE@% as a context string. The minimally formatted ASCII
  7722. help file must begin with the help delimiter (>>), so that HELPMAKE or the
  7723. application can verify that the file is indeed an ASCII help file.  %@NL@%
  7724. %@NL@%
  7725. %@AS@%  >>>>open
  7726. %@AS@%  
  7727. %@AS@%  Include:    <fcntl.h>, <io.h>, <sys\types.h>, <sys\stat.h>
  7728. %@AS@%  
  7729. %@AS@%  Prototype:  int open(char *path, int flag[, int mode]);
  7730. %@AS@%          flag:  O_APPEND  O_BINARY  O_CREAT  O_EXCL  O_RDONLY
  7731. %@AS@%                 O_RDWR    O_TEXT    O_TRUNC  O_WRONLY
  7732. %@AS@%                 (can be joined by |)
  7733. %@AS@%          mode:  S_IWRITE  S_IREAD   S_IREAD | S_IWRITE
  7734. %@AS@%  
  7735. %@AS@%  Returns:    a handle if successful, or -1 if not.
  7736. %@AS@%              errno:  EACCES, EEXIST, EMFILE, ENOENT%@AE@%%@NL@%
  7737. %@NL@%
  7738. %@AS@%  See also:  access, chmod, close, creat, dup, dup2, fopen, sopen, umask%@AE@%%@NL@%
  7739. %@NL@%
  7740. When displayed, the help information appears exactly as it is typed into the
  7741. file. Any formatting codes are treated as ASCII text. Note that you do not
  7742. need to escape backslashes in minimally formatted ASCII files.  %@NL@%
  7743. %@NL@%
  7744. If you compress minimally formatted ASCII files, they are smaller and faster
  7745. to search.  %@NL@%
  7746. %@NL@%
  7747. %@NL@%
  7748. %@3@%%@CR:C6A00070023 @%%@AB@%7.6.3  Rich Text Format (RTF)%@AE@%%@EH@%%@NL@%
  7749. %@NL@%
  7750. RTF is a Microsoft word-processing format supported by many other word
  7751. processors. It allows documents to be transferred from one application to
  7752. another without losing any formatting information. The HELPMAKE utility
  7753. recognizes a subset of the full RTF syntax. If your file contains any RTF
  7754. code that is not part of the subset, HELPMAKE ignores the code and strips it
  7755. out of the file.  %@NL@%
  7756. %@NL@%
  7757. Certain word-processing and file-conversion programs generate the RTF code
  7758. automatically as output. You need not worry about inserting RTF codes
  7759. yourself; you can simply format your help files directly with a
  7760. word-processor that generates RTF, using the attributes supported by the
  7761. subset. The only items you need to insert are the help delimiter (>>) and
  7762. context string that start each entry.  %@NL@%
  7763. %@NL@%
  7764. HELPMAKE recognizes the subset of RTF listed below:  %@NL@%
  7765. %@NL@%
  7766. %@AB@%RTF Code%@AE@%                          %@AB@%Action%@AE@%
  7767. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7768. \b                                Boldface. The application decides how to
  7769.                                   display this; often it is intensified 
  7770.                                   text.
  7771.  
  7772. \fi <%@AI@%nnn%@AE@%>                         Paragraph first-line indent.
  7773.  
  7774. \i                                Italic. The application decides how to 
  7775.                                   display this; often it is reverse video.
  7776.  
  7777. \li <%@AI@%nnn%@AE@%>                         Paragraph indent from left margin.
  7778.  
  7779. \line                             New line (not new paragraph).
  7780.  
  7781. \par                              End of paragraph.
  7782.  
  7783. \pard                             Default paragraph formatting.
  7784.  
  7785. \plain                            Default attributes. On most screens this
  7786.                                   is nonblinking normal intensity.
  7787.  
  7788. \tab                              Tab character.
  7789.  
  7790. \ul                               Underline. The application decides how 
  7791.                                   to display this; some adapters that do 
  7792.                                   not support underlining display it as 
  7793.                                   blue text.
  7794.  
  7795. \v                                Hidden text. Hidden text is used for 
  7796.                                   cross-reference information and for some
  7797.                                   application-specific communications; it 
  7798.                                   is not displayed.
  7799.  
  7800. Using the word-processing program, you can break the topic text into
  7801. paragraphs. When HELPMAKE compresses the file, it formats the text to the
  7802. width given with the / W option, ignoring the paragraph formats.  %@NL@%
  7803. %@NL@%
  7804. As with the other text formats, each entry in the database source consists
  7805. of one or more context strings, followed by topic text. An RTF file can
  7806. contain QuickHelp dot commands.  %@NL@%
  7807. %@NL@%
  7808. The help delimiter (>>) at the beginning of any paragraph denotes the
  7809. beginning of a new help entry. The text that follows on the same line is
  7810. defined as a context for the topic. If the next paragraph also begins with
  7811. the help delimiter, it also defines a context string for the same topic
  7812. text. You can define any number of contexts for a block of topic text. The
  7813. topic text comprises all subsequent paragraphs up to the next paragraph that
  7814. begins with the help delimiter.  %@NL@%
  7815. %@NL@%
  7816. The code below is an example of a help database that contains a single entry
  7817. using subset RTF text. Note that RTF uses curly braces ({}) for nesting.
  7818. Thus, the entire file is enclosed in curly braces, as is each specially
  7819. formatted text item.  %@NL@%
  7820. %@NL@%
  7821. %@AS@%  {\rtf1
  7822. %@AS@%  \pard >>open\par 
  7823. %@AS@%    {\b Include:}    <fcntl.h>, <io.h>, <sys\\types.h>, <sys\\stat.h>\par
  7824. %@AS@%  \par 
  7825. %@AS@%    {\b Syntax:}     int open( char * filename, int oflag[, int pmode ]
  7826. %@AS@%);\par
  7827. %@AS@%               oflag:  O_APPEND  O_BINARY  O_CREAT  O_EXCL  O_RDONLY\par 
  7828. %@AS@%                       O_RDWR    O_TEXT    O_TRUNC  O_WRONLY\par 
  7829. %@AS@%                       (may be joined by |)\par 
  7830. %@AS@%               pmode:  S_IWRITE  S_IREAD   S_IREAD | S_IWRITE\par 
  7831. %@AS@%  \par 
  7832. %@AS@%    {\b Returns:}    a handle if successful, or -1 if not.\par
  7833. %@AS@%               errno:  EACCES, EEXIST, EMFILE, ENOENT\par 
  7834. %@AS@%  \par 
  7835. %@AS@%    {\b See also:}  Examples{\v open.ex}, access, chmod, close, creat,
  7836. %@AS@%dup,\par
  7837. %@AS@%               dup2, fopen, sopen, umask\par 
  7838. %@AS@%  >>open.ex\par 
  7839. %@AS@%  To build this help file, use the following command:\par
  7840. %@AS@%  \par
  7841. %@AS@%  HELPMAKE /S1 /E15 /OOPEN.HLP OPEN.RTF\par
  7842. %@AS@%  \par
  7843. %@AS@%  
  7844. %@AS@%          < Back >{\v !B}
  7845. %@AS@%  }%@AE@%%@NL@%
  7846. %@NL@%
  7847. Actual RTF output normally contains additional information that is not
  7848. visible to the user; HELPMAKE ignores this extra information.  %@NL@%
  7849. %@NL@%
  7850. %@NL@%
  7851. %@NL@%
  7852. %@NL@%
  7853. %@NL@%
  7854. %@NL@%
  7855. %@CR:C6A00080001 @%%@1@%%@AB@%Chapter 8  Customizing the Microsoft Programmer's WorkBench%@AE@%%@EH@%%@NL@%
  7856. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7857. %@NL@%
  7858. Designed with flexibility in mind, the Microsoft Programmer's WorkBench
  7859. (PWB) provides a highly extensible development platform for the Microsoft C
  7860. Professional Development System. Using PWB it is easy to change basic
  7861. environment features such as screen colors and key assignments, and you can
  7862. add powerful new functions of your own using macros and C-language
  7863. extensions.  %@NL@%
  7864. %@NL@%
  7865. This chapter explains four methods for customizing the Programmer's
  7866. WorkBench: setting switches, assigning keystrokes, writing macros, and
  7867. writing C extensions. While it explains customization methods, the chapter
  7868. does not document every customizable feature of the Programmer's WorkBench.
  7869. Use on-line help as your primary source of information about these and other
  7870. PWB features.  %@NL@%
  7871. %@NL@%
  7872. This chapter assumes you are familiar with basic PWB operations and
  7873. terminology. If you are not, read "Using the Programmer's WorkBench" in
  7874. %@AI@%Installing and Using the Microsoft C Professional Development System%@AE@%.  %@NL@%
  7875. %@NL@%
  7876. %@NL@%
  7877. %@2@%%@CR:C6A00080002 @%%@AB@%8.1  Setting Switches%@AE@%%@EH@%%@NL@%
  7878. %@NL@%
  7879. The Programmer's WorkBench has a number of "switches," or user-configurable
  7880. options, that control features such as screen colors. Each switch has a name
  7881. and can be assigned a value.  %@NL@%
  7882. %@NL@%
  7883. There are two ways to set PWB switches. The easiest way is by choosing
  7884. Editor Settings in the Options menu. You can also edit the TOOLS.INI
  7885. initialization file. These methods can also be used for more elaborate
  7886. customizations, such as writing macros.  %@NL@%
  7887. %@NL@%
  7888. %@NL@%
  7889. %@3@%%@CR:C6A00080003 @%%@AB@%8.1.1  Editing the <assign> Pseudofile%@AE@%%@EH@%%@NL@%
  7890. %@NL@%
  7891. If you choose Editor Settings in the Options menu, PWB changes to the
  7892. %@AB@%<assign>%@AE@% pseudofile and displays it in the current window. (A pseudofile is
  7893. constructed dynamically by PWB; it exists only in memory.) The %@AB@%<assign>%@AE@%
  7894. file lists all the current PWB settings.  %@NL@%
  7895. %@NL@%
  7896. To change a switch, edit the line where it appears. For instance, the
  7897. %@AB@%vscroll%@AE@% switch controls how many lines PWB scrolls vertically; its default
  7898. setting is 1. To change it, move to the corresponding line:  %@NL@%
  7899. %@NL@%
  7900. %@AS@%  vscroll:1%@AE@%%@NL@%
  7901. %@NL@%
  7902. Change the 1 to 3 and move the cursor to another line. PWB highlights the
  7903. line to indicate the change is legal. (If you make an illegal change, PWB
  7904. signals an error.) The change takes effect immediately: now PWB scrolls text
  7905. three vertical lines at a time.  %@NL@%
  7906. %@NL@%
  7907. If you don't explicitly save a change, it disappears at the end of the
  7908. current session. You can save a change by saving %@AB@%<assign>%@AE@% as you would any
  7909. other file (by pressing ALT+A ALT+A F2). When you exit PWB, you are asked if
  7910. you want to save TOOLS.INI, the PWB initialization file, which records
  7911. customizations. Answer yes (type %@AS@% Y) %@AE@% to save the change.  %@NL@%
  7912. %@NL@%
  7913. You can also use this method for more elaborate customizations, such as
  7914. writing macros (see Section 8.3, "Writing Macros"). Simply insert a few
  7915. blank lines in %@AB@%<assign>%@AE@% and enter the new information in them. Note that PWB
  7916. only pays attention to lines you change or add to %@AB@%<assign>%@AE@%. Deleting a line
  7917. has no effect.  %@NL@%
  7918. %@NL@%
  7919. %@NL@%
  7920. %@3@%%@CR:C6A00080004 @%%@AB@%8.1.2  Editing the TOOLS.INI Initialization File%@AE@%%@EH@%%@NL@%
  7921. %@NL@%
  7922. Another way to customize PWB is by editing TOOLS.INI, the initialization
  7923. file used by PWB and other Microsoft language tools. This method is useful
  7924. if you customize PWB extensively.  %@NL@%
  7925. %@NL@%
  7926. While the %@AB@%<assign>%@AE@% file lists every customizable PWB item, the TOOLS.INI
  7927. file contains lines only for items you have customized. Those items not
  7928. mentioned in TOOLS.INI are set to a default value.  %@NL@%
  7929. %@NL@%
  7930. %@NL@%
  7931. %@4@%%@AB@%Dividing TOOLS.INI into Sections%@AE@%%@EH@%%@NL@%
  7932. %@NL@%
  7933. Since several tools can use TOOLS.INI, the file may contain information that
  7934. doesn't relate to PWB. If you customize more than one tool, TOOLS.INI is
  7935. divided into sections, one for each tool. Each section begins with a tag
  7936. consisting of the tool's base name enclosed in square brackets: %@AS@% [PWB] %@AE@% for
  7937. PWB.EXE, %@AS@%[NMAKE] %@AE@% for NMAKE.EXE, and so on.  %@NL@%
  7938. %@NL@%
  7939. For example, say you set the %@AB@%vscroll%@AE@% switch to 3 and save the change, but
  7940. you have not customized PWB in any other way. Your TOOLS.INI file will
  7941. contain this section:  %@NL@%
  7942. %@NL@%
  7943. %@AS@%  [PWB]
  7944. %@AS@%  vscroll:3%@AE@%%@NL@%
  7945. %@NL@%
  7946. Settings following this tag are put in effect by PWB every time it starts.  %@NL@%
  7947. %@NL@%
  7948. You can also create sections of TOOLS.INI that PWB reads only in certain
  7949. circumstances. You can create sections for different video adapters,
  7950. file-name extensions, and operating system versions.  %@NL@%
  7951. %@NL@%
  7952. If you use more than one video display, TOOLS.INI can have a different
  7953. section for each display:  %@NL@%
  7954. %@NL@%
  7955. %@NL@%
  7956.   ■   %@AS@%[PWB-mono]%@AE@%%@NL@%
  7957. %@NL@%
  7958.   ■   %@AS@%[PWB-cga]%@AE@%%@NL@%
  7959. %@NL@%
  7960.   ■   %@AS@%[PWB-ega]%@AE@%%@NL@%
  7961. %@NL@%
  7962.   ■   %@AS@%[PWB-vga]%@AE@%%@NL@%
  7963. %@NL@%
  7964. %@NL@%
  7965. After each tag, you can set different screen colors, dimensions, and other
  7966. display-specific switches.  %@NL@%
  7967. %@NL@%
  7968. You can also create a section for files with specific extensions. For
  7969. instance, your TOOLS.INI file could contain a section beginning with the tag
  7970. %@NL@%
  7971. %@NL@%
  7972. %@AS@%  [PWB-.C]%@AE@%%@NL@%
  7973. %@NL@%
  7974. for C source files, and  %@NL@%
  7975. %@NL@%
  7976. %@AS@%  [PWB-.ASM]%@AE@%%@NL@%
  7977. %@NL@%
  7978. for assembly-language (.ASM) source files. Each time you load a file with
  7979. the designated extension, PWB reads the appropriate section of TOOLS.INI.
  7980. For each file type, you could use a different set of macros and other
  7981. customizations.  %@NL@%
  7982. %@NL@%
  7983. TOOLS.INI can also contain sections specific to operating system versions.
  7984. The following tag introduces a section specific to DOS version 3.20, for
  7985. instance:  %@NL@%
  7986. %@NL@%
  7987. %@AS@%  [PWB-3.20]%@AE@%%@NL@%
  7988. %@NL@%
  7989. You can combine tags as needed. For example, the tag  %@NL@%
  7990. %@NL@%
  7991. %@AS@%  [PWB-3.20 PWB-10.10R]%@AE@%%@NL@%
  7992. %@NL@%
  7993. applies to DOS version 3.20 and OS/2 version 1.1 real mode.  %@NL@%
  7994. %@NL@%
  7995. You can also create a section in TOOLS.INI containing switches for a
  7996. userwritten extension. See Section 8.4.3, "Describing Functions and
  7997. Switches." On-line help contains additional information about TOOLS.INI
  7998. tags.  %@NL@%
  7999. %@NL@%
  8000. %@NL@%
  8001. %@2@%%@CR:C6A00080005 @%%@AB@%8.2  Assigning Keystrokes%@AE@%%@EH@%%@NL@%
  8002. %@NL@%
  8003. PWB allows you to assign any editing function to almost any keystroke.
  8004. Reassigning keystrokes doesn't change PWB graphic interface, however.  %@NL@%
  8005. %@NL@%
  8006. Keystrokes, like switches, are listed in the %@AB@%<assign>%@AE@% pseudofile (choose Key
  8007. Assignments in the Options menu) and can be changed there. For example, say
  8008. you want to assign the %@AB@%home%@AE@% cursor function to the SHIFT+HOME keystroke. The
  8009. default keystroke assignment for %@AB@%home%@AE@% is:  %@NL@%
  8010. %@NL@%
  8011. %@AS@%  home:ctrl+home%@AE@%%@NL@%
  8012. %@NL@%
  8013. If you change the assignment to  %@NL@%
  8014. %@NL@%
  8015. %@AS@%  home:shift+home%@AE@%%@NL@%
  8016. %@NL@%
  8017. SHIFT+HOME moves the cursor to the home (upper left) window position.  %@NL@%
  8018. %@NL@%
  8019. It is legal to assign more than one keystroke to the same function. For
  8020. example, many keystrokes invoke the %@AB@%select%@AE@% function, which selects a text
  8021. region. Thus, the previous example adds a new keystroke (SHIFT+HOME) for the
  8022. %@AB@%home%@AE@% function; it does not remove the previous assignment (CTRL+HOME).  %@NL@%
  8023. %@NL@%
  8024. There are two limitations on keystroke assignments:  %@NL@%
  8025. %@NL@%
  8026. %@NL@%
  8027.   ■   You can't reassign a keystroke that PWB is using for a menu. For
  8028.       instance, if ALT+F pulls down the File menu, PWB ignores any attempt
  8029.       to reassign ALT+F.%@NL@%
  8030. %@NL@%
  8031.   ■   You can't reassign ALT plus the number keys 1 - 9 (ALT+1, ALT+2, and
  8032.       so on). These keystrokes are reserved for the file history menu items.%@NL@%
  8033. %@NL@%
  8034. %@NL@%
  8035. Each keystroke can only invoke one function. If you mistakenly assign a
  8036. key-stroke to more than one function, PWB uses the most recent assignment.
  8037. For example,  %@NL@%
  8038. %@NL@%
  8039. %@AS@%  home:ctrl+a
  8040. %@AS@%  setfile:ctrl+a%@AE@%%@NL@%
  8041. %@NL@%
  8042. assigns the CTRL+A keystroke to two different functions, %@AB@%home%@AE@% and %@AB@%setfile%@AE@%.
  8043. The second assignment overrides the first, assigning CTRL+A to %@AB@%setfile%@AE@%.  %@NL@%
  8044. %@NL@%
  8045. Occasionally, you may want to "unassign," or disable, a keystroke. This is
  8046. done by assigning the %@AB@%unassigned%@AE@% function to the keystroke. For example,  %@NL@%
  8047. %@NL@%
  8048. %@AS@%  unassigned:ctrl+a%@AE@%%@NL@%
  8049. %@NL@%
  8050. disables CTRL+A. PWB signals an error when you press any unassigned key.  %@NL@%
  8051. %@NL@%
  8052. %@NL@%
  8053. %@2@%%@CR:C6A00080006 @%%@AB@%8.3  Writing Macros%@AE@%%@EH@%%@NL@%
  8054. %@NL@%
  8055. The fastest way to create a new editing function for PWB is to write a
  8056. macro. The function can be as simple as inserting a long word or phrase, or
  8057. it can perform complex tasks by invoking PWB functions and other macros.  %@NL@%
  8058. %@NL@%
  8059. %@NL@%
  8060. %@3@%%@CR:C6A00080007 @%%@AB@%8.3.1  Macro Syntax%@AE@%%@EH@%%@NL@%
  8061. %@NL@%
  8062. A macro can contain any combination of PWB functions, literal text, and
  8063. macro operators. You can define as many as 1,024 macros at one time.  %@NL@%
  8064. %@NL@%
  8065. %@AU@% Literal text is case sensitive.%@AE@%  %@NL@%
  8066. %@NL@%
  8067. Literal text is anything inside double quotes. Inside literal text, you can
  8068. represent a double quote as %@AS@% \"%@AE@% and a backslash as %@AS@% \\%@AE@%. Text is case
  8069. sensitive inside quotes and case insensitive outside them.  %@NL@%
  8070. %@NL@%
  8071. The following macro comments out a line of C source code:  %@NL@%
  8072. %@NL@%
  8073. %@AS@%  comment:=begline "/* " endline " */"
  8074. %@AS@%  comment:alt+c%@AE@%%@NL@%
  8075. %@NL@%
  8076. The first line names the macro and tells what it does. The %@AB@%begline%@AE@% and
  8077. %@AB@%endline%@AE@% editor functions move the cursor, while the text inside quotes is
  8078. printed at the current cursor position. The second line assigns a keystroke
  8079. (ALT+C) to the macro.  %@NL@%
  8080. %@NL@%
  8081. A macro definition must fit on one logical line. If necessary, you can use
  8082. the backslash ( \ ) to continue the definition on the next line. For
  8083. instance, the definition  %@NL@%
  8084. %@NL@%
  8085. %@AS@%  comment:=begline "/* " endline " */"%@AE@%%@NL@%
  8086. %@NL@%
  8087. could be written as  %@NL@%
  8088. %@NL@%
  8089. %@AS@%  comment:=begline  \
  8090. %@AS@%  "/* " endline  \
  8091. %@AS@%  " */"%@AE@%%@NL@%
  8092. %@NL@%
  8093. Notice the extra space before each backslash. If you want a space between
  8094. the end of one line and the beginning of the other, you must precede the
  8095. backslash with two spaces.  %@NL@%
  8096. %@NL@%
  8097. You can use the %@AB@%arg%@AE@% function to pass arguments to functions. For example,
  8098. the following macro passes the argument %@AS@% 15 %@AE@% to the %@AB@%plines%@AE@% function (which
  8099. scrolls text down):  %@NL@%
  8100. %@NL@%
  8101. %@AS@%  movedown:=arg "15" plines%@AE@%%@NL@%
  8102. %@NL@%
  8103. Because %@AB@%arg%@AE@% precedes the literal text, the text doesn't appear on the
  8104. screen. Instead, it is passed as an argument to the next function, %@AB@%plines%@AE@%.
  8105. The macro scrolls the current text down 15 lines.  %@NL@%
  8106. %@NL@%
  8107. Arguments can use regular expression syntax, as well (regular expressions
  8108. are documented in on-line help):  %@NL@%
  8109. %@NL@%
  8110. %@AS@%  endword:=arg arg "( !.!$!\\:!;!\\)!\\(!,)" psearch%@AE@%%@NL@%
  8111. %@NL@%
  8112. The %@AB@%arg arg%@AE@% sequence directs the %@AB@%psearch%@AE@% function to treat the text argument
  8113. as a regular expression search pattern. This search pattern tells PWB to
  8114. search for the next period, end of line ($), colon, semicolon, close
  8115. parenthesis, open parenthesis, or comma.  %@NL@%
  8116. %@NL@%
  8117. A macro can invoke other macros:  %@NL@%
  8118. %@NL@%
  8119. %@AS@%  lcomment:= "/* "
  8120. %@AS@%  rcomment:= " */"
  8121. %@AS@%  commentout:=begline lcomment endline rcomment
  8122. %@AS@%  commentout:alt+z%@AE@%%@NL@%
  8123. %@NL@%
  8124. The %@AS@% commentout %@AE@% macro invokes the previously defined macros %@AS@% lcomment %@AE@% and %@AS@%
  8125. %@AS@%rcomment.%@AE@%  %@NL@%
  8126. %@NL@%
  8127. In addition to standard PWB functions, macros can invoke user-defined
  8128. (extension) functions. See Section 8.4, "Writing and Building C Extensions."
  8129. %@NL@%
  8130. %@NL@%
  8131. %@NL@%
  8132. %@3@%%@CR:C6A00080008 @%%@AB@%8.3.2  Macro Responses%@AE@%%@EH@%%@NL@%
  8133. %@NL@%
  8134. Some PWB functions ask you for confirmation. For example, the %@AB@%meta exit%@AE@%
  8135. (quit without saving) function normally asks if you really want to exit.
  8136. Such questions always take the answer "yes" (%@AS@%y%@AE@%) or "no" (%@AS@%n%@AE@%).  %@NL@%
  8137. %@NL@%
  8138. When you invoke such a function in a macro, the function assumes an answer
  8139. of yes and does not ask for confirmation. For example, the macro definition
  8140. %@NL@%
  8141. %@NL@%
  8142. %@AS@%  quit:=meta exit
  8143. %@AS@%  quit:alt+x%@AE@%%@NL@%
  8144. %@NL@%
  8145. invokes %@AB@%meta exit%@AE@% when you press ALT+X. Because the %@AB@%meta exit%@AE@% function is
  8146. invoked from a macro, PWB exits without asking for confirmation.  %@NL@%
  8147. %@NL@%
  8148. The following operators allow you to restore normal prompting or change the
  8149. default responses:  %@NL@%
  8150. %@NL@%
  8151. %@AB@%Operator%@AE@%                          %@AB@%Description%@AE@%
  8152. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8153. %@AB@%<%@AE@%                                 Asks for confirmation; if not followed 
  8154.                                   by another %@AB@%<%@AE@% operator, prompts for all 
  8155.                                   further questions
  8156.  
  8157. %@AB@%<y%@AE@%                                Assumes a response of yes
  8158.  
  8159. %@AB@%<n%@AE@%                                Assumes a response of no
  8160.  
  8161. A response operator applies to the function immediately preceding it. For
  8162. instance, you can add the %@AB@%%@AE@% operator to the %@AS@% quit %@AE@% macro definition to
  8163. restore the usual prompt:  %@NL@%
  8164. %@NL@%
  8165. %@AS@%  quit:=meta exit <
  8166. %@AS@%  quit:alt+x%@AE@%%@NL@%
  8167. %@NL@%
  8168. Now the macro prompts for a response before it exits.  %@NL@%
  8169. %@NL@%
  8170. %@NL@%
  8171. %@3@%%@CR:C6A00080009 @%%@AB@%8.3.3  Macro Arguments%@AE@%%@EH@%%@NL@%
  8172. %@NL@%
  8173. If you enter an argument in PWB and then invoke a macro, the argument is
  8174. passed to the first function in the macro that takes an argument:  %@NL@%
  8175. %@NL@%
  8176. %@AS@%  tripleit:=copy paste paste%@AE@%%@NL@%
  8177. %@NL@%
  8178. The %@AS@% tripleit %@AE@% macro invokes the %@AB@%copy%@AE@% and %@AB@%paste%@AE@% editing functions. If you
  8179. highlight a text area and then invoke the macro, your highlighted argument
  8180. is passed to the %@AB@%copy%@AE@% function, which copies the argument to the clipboard.
  8181. The macro then invokes %@AB@%paste%@AE@% twice. The effect is to insert two copies of
  8182. the highlighted text.  %@NL@%
  8183. %@NL@%
  8184. %@AU@% You cannot pass more than one argument from PWB to a macro.%@AE@%  %@NL@%
  8185. %@NL@%
  8186. You cannot pass more than one argument from PWB to a macro, even if the
  8187. macro invokes more than one function that can accept an argument. The
  8188. argument always goes to the first function in the macro that takes an
  8189. argument.  %@NL@%
  8190. %@NL@%
  8191. You can also prompt for input inside a macro and pass the input as an
  8192. argument using the %@AB@%prompt%@AE@% function as shown below:  %@NL@%
  8193. %@NL@%
  8194. %@AS@%  newfile:=arg "Next file: " prompt setfile <
  8195. %@AS@%  newfile:alt+n%@AE@%%@NL@%
  8196. %@NL@%
  8197. The %@AS@% newfile %@AE@% macro prompts for a file name and then switches to the
  8198. specified file. The sequence %@AS@% arg "Next file: "%@AE@% passes a text argument to
  8199. %@AB@%prompt%@AE@%, which prints the text on the dialog line and waits for input. The
  8200. input is passed as a text argument to the %@AB@%setfile%@AE@% function, which switches
  8201. to that file. For more information on the %@AB@%prompt%@AE@% function, see on-line help.
  8202. %@NL@%
  8203. %@NL@%
  8204. %@NL@%
  8205. %@3@%%@CR:C6A00080010 @%%@AB@%8.3.4  Macro Conditionals%@AE@%%@EH@%%@NL@%
  8206. %@NL@%
  8207. Macros can take different actions depending on certain conditions. Such
  8208. macros take advantage of the fact that PWB editing functions generally
  8209. return values─a TRUE (nonzero) value if successful or FALSE (zero) if
  8210. unsuccessful.  %@NL@%
  8211. %@NL@%
  8212. Macros can use four conditional operators:  %@NL@%
  8213. %@NL@%
  8214. %@AB@%Operator%@AE@%                          %@AB@%Description%@AE@%
  8215. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8216. %@AB@%:>%@AE@%%@AI@%label%@AE@%                           Defines a %@AI@%label%@AE@% that can be targeted by 
  8217.                                   other operators
  8218.  
  8219. %@AB@%=>%@AE@%%@AI@%label%@AE@%                           Jumps to %@AI@%label%@AE@%
  8220.  
  8221. %@AB@%+>%@AE@%%@AI@%label%@AE@%                           Jumps to %@AI@%label%@AE@% if the previous function 
  8222.                                   returns TRUE
  8223.  
  8224. %@AB@%->%@AE@%%@AI@%label%@AE@%                           Jumps to %@AI@%label%@AE@% if the previous function 
  8225.                                   returns FALSE
  8226.  
  8227. For example, the %@AS@% leftmarg %@AE@% macro moves the cursor to the left margin of the
  8228. editing window:  %@NL@%
  8229. %@NL@%
  8230. %@AS@%  leftmarg:=:>leftmore left +>leftmore%@AE@%%@NL@%
  8231. %@NL@%
  8232. The macro above invokes the %@AB@%left%@AE@% function repeatedly (jumping to the label %@AS@%
  8233. %@AS@%%@AE@%leftmore) until it returns FALSE, indicating the cursor has reached the left
  8234. margin.  %@NL@%
  8235. %@NL@%
  8236. The label must appear immediately after the conditional operator, with no
  8237. intervening spaces. A conditional operator without a label exits the macro
  8238. immediately if the condition is true. If the condition is false, the macro
  8239. continues execution. The following example demonstrates this:  %@NL@%
  8240. %@NL@%
  8241. %@AS@%  turnon:=insertmode +> insertmode%@AE@%%@NL@%
  8242. %@NL@%
  8243. This macro turns on insert mode regardless of whether insert mode is
  8244. currently on or off. If insert mode is off, the first invocation of
  8245. %@AB@%insertmode%@AE@% toggles the mode on and returns TRUE, causing the %@AB@%+>%@AE@% operator to
  8246. terminate the macro. If insert mode is currently on, the first invocation of
  8247. %@AB@%insertmode%@AE@% turns insert mode off and returns FALSE. The macro then invokes
  8248. %@AB@%insertmode%@AE@% a second time, turning insert mode back on.  %@NL@%
  8249. %@NL@%
  8250. %@NL@%
  8251. %@3@%%@CR:C6A00080011 @%%@AB@%8.3.5  Temporary Macros%@AE@%%@EH@%%@NL@%
  8252. %@NL@%
  8253. Occasionally, you may want to create a macro that lasts only through the
  8254. current session. This can be done with the %@AB@%assign%@AE@% function. For example, the
  8255. following steps create the %@AS@% comment %@AE@% macro described above.  %@NL@%
  8256. %@NL@%
  8257. To create the macro:  %@NL@%
  8258. %@NL@%
  8259. %@NL@%
  8260.   ■   Press ALT+A%@NL@%
  8261. %@NL@%
  8262.   ■   Type %@AS@% %@AE@%comment:=begline "/* " endline " */" %@NL@%
  8263. %@NL@%
  8264.   ■   Press ALT+=%@NL@%
  8265. %@NL@%
  8266. %@NL@%
  8267. To assign the ALT+C keystroke to the macro:  %@NL@%
  8268. %@NL@%
  8269. %@NL@%
  8270.   ■   Press ALT+A%@NL@%
  8271. %@NL@%
  8272.   ■   Type %@AS@% %@AE@%comment:alt+c%@NL@%
  8273. %@NL@%
  8274.   ■   Press ALT+=%@NL@%
  8275. %@NL@%
  8276. %@NL@%
  8277. The macro is available immediately and then disappears at the end of the
  8278. current session.  %@NL@%
  8279. %@NL@%
  8280. %@NL@%
  8281. %@3@%%@CR:C6A00080012 @%%@AB@%8.3.6  Macro Recordings%@AE@%%@EH@%%@NL@%
  8282. %@NL@%
  8283. Another way to create a macro is by recording your own actions. The entire
  8284. sequence of actions is saved and can be replayed later by pressing a key.  %@NL@%
  8285. %@NL@%
  8286. You start the recording by invoking the %@AB@%record%@AE@% function. PWB names the
  8287. resulting macro %@AB@%recordvalue%@AE@% by default, but you can use other names as well.
  8288. To record a macro:  %@NL@%
  8289. %@NL@%
  8290. %@NL@%
  8291.   ■   Choose Record On from the Edit menu to start the recording.%@NL@%
  8292. %@NL@%
  8293.   ■   Perform the actions you want to record.%@NL@%
  8294. %@NL@%
  8295.   ■   Choose Record On again to end the recording.%@NL@%
  8296. %@NL@%
  8297.   ■   If %@AB@%recordvalue%@AE@% is not already assigned, assign it to a keystroke as
  8298.       described above.%@NL@%
  8299. %@NL@%
  8300. %@NL@%
  8301. After you complete these steps, a macro named %@AB@%recordvalue%@AE@% is available
  8302. through the keystroke you assigned in the last step above. When you press
  8303. this key, PWB replays the actions you recorded.  %@NL@%
  8304. %@NL@%
  8305. If you don't do anything more, the recorded macro is temporary─it disappears
  8306. when you exit PWB. To save the macro permanently:  %@NL@%
  8307. %@NL@%
  8308. %@NL@%
  8309.   ■   Open the %@AB@%<record>%@AE@% pseudofile (press ALT+A, type %@AS@% <record>%@AE@%, press F2).%@NL@%
  8310. %@NL@%
  8311.   ■   Copy the macro definition in %@AB@%<record>%@AE@%.%@NL@%
  8312. %@NL@%
  8313.   ■   Paste the definition into the %@AS@% [PWB] %@AE@% section of your TOOLS.INI file.%@NL@%
  8314. %@NL@%
  8315. %@NL@%
  8316. Studying recorded macros can teach you a lot about macros and editor
  8317. functions. If you open the %@AB@%<record>%@AE@% pseudofile in a second window before you
  8318. record, you can watch PWB write the macro definition function by function.  %@NL@%
  8319. %@NL@%
  8320. If you save a recorded macro, you'll want to name it something other than
  8321. %@AB@%recordvalue,%@AE@% the default name. To do this, pass the new name as an argument
  8322. when you start the recording:  %@NL@%
  8323. %@NL@%
  8324. %@NL@%
  8325.   ■   Press ALT+A ALT+A.%@NL@%
  8326. %@NL@%
  8327.   ■   Type the new name.%@NL@%
  8328. %@NL@%
  8329.   ■   Choose Record On from the Edit menu to start recording.%@NL@%
  8330. %@NL@%
  8331.   ■   Complete the recording as usual.%@NL@%
  8332. %@NL@%
  8333. %@NL@%
  8334. You can expand an existing macro using the same process. If you supply the
  8335. name of an existing macro, PWB appends the recorded commands to the macro
  8336. instead of replacing it.  %@NL@%
  8337. %@NL@%
  8338. %@AU@% You can record a series  of actions without  executing them.%@AE@%  %@NL@%
  8339. %@NL@%
  8340. You can also make a "silent" recording, which records a series of actions
  8341. without executing them. Start the recording with a %@AB@%meta record%@AE@% command
  8342. (press F9 SHIFT+CTRL+R). Then complete the recording process as described
  8343. above.  %@NL@%
  8344. %@NL@%
  8345. %@NL@%
  8346. %@2@%%@CR:C6A00080013 @%%@AB@%8.4  Writing and Building C Extensions%@AE@%%@EH@%%@NL@%
  8347. %@NL@%
  8348. An "extension" is a file containing one or more user-written functions. PWB
  8349. loads extensions at run time. Once the extension has been loaded, its
  8350. functions can be assigned their own keystrokes, given arguments, and invoked
  8351. in macros, exactly like other PWB functions.  %@NL@%
  8352. %@NL@%
  8353. %@AU@% User-written functions execute more quickly than macros.%@AE@%  %@NL@%
  8354. %@NL@%
  8355. The ability to load and call user-written functions makes PWB highly
  8356. extensible. Because they consist of compiled C code, your functions can
  8357. perform more complex jobs than macros can, and they execute many times
  8358. faster.  %@NL@%
  8359. %@NL@%
  8360. An extension contains executable code, but it differs from a normal
  8361. executable file in some important ways:%@CR:C6A00080014 @%  %@NL@%
  8362. %@NL@%
  8363. %@NL@%
  8364.   ■   It does not contain the usual C start-up code.%@NL@%
  8365. %@NL@%
  8366.   ■   It contains special data structures that describe its functions to
  8367.       PWB.%@NL@%
  8368. %@NL@%
  8369.   ■   Its functions are declared in a form that allows PWB to call them and
  8370.       pass arguments to them.%@NL@%
  8371. %@NL@%
  8372.   ■   Its functions can call native PWB functions, and some, but not all, C
  8373.       library functions.%@NL@%
  8374. %@NL@%
  8375. %@NL@%
  8376. This section explains how to build, load, and invoke a PWB extension. The
  8377. example, CENTER.C, serves as a basis for discussion throughout the rest of
  8378. this chapter.%@CR:C6A00080015 @%%@CR:C6A00080016 @%  %@NL@%
  8379. %@NL@%
  8380. The CENTER.C extension contains one extension function, %@AS@% %@AE@%CenterLine, which
  8381. centers a line or range of lines in the current file.  %@NL@%
  8382. %@NL@%
  8383. %@AS@%  /* CENTER.C: Sample PWB extension */
  8384. %@AS@%  
  8385. %@AS@%  #define LINE_LENGTH 80 /* Assumes 80-column screen */
  8386. %@AS@%  
  8387. %@AS@%  #include <string.h>
  8388. %@AS@%  /* PWB extension header file */
  8389. %@AS@%  #include "ext.h"
  8390. %@AS@%  
  8391. %@AS@%  PWBFUNC CenterLine( unsigned argData,
  8392. %@AS@%                      ARG _far *pArg,
  8393. %@AS@%                      flagType fMeta );
  8394. %@AS@%  
  8395. %@AS@%  /* Switch Table */
  8396. %@AS@%  struct swiDesc   swiTable[] =
  8397. %@AS@%  {
  8398. %@AS@%     { NULL, NULL, 0 }
  8399. %@AS@%  };
  8400. %@AS@%  
  8401. %@AS@%  /* Command Table */
  8402. %@AS@%  struct cmdDesc   cmdTable[] =
  8403. %@AS@%  {
  8404. %@AS@%     { "CenterLine", CenterLine, 0, NOARG | LINEARG },
  8405. %@AS@%     { NULL, NULL, 0, 0 }
  8406. %@AS@%  };
  8407. %@AS@%  
  8408. %@AS@%  /* Initialization Function */
  8409. %@AS@%  void EXTERNAL WhenLoaded( void )
  8410. %@AS@%  {
  8411. %@AS@%     DoMessage( "Loading Center extension" );
  8412. %@AS@%  }
  8413. %@AS@%  
  8414. %@AS@%  /* Extension (user-written) function */
  8415. %@AS@%  PWBFUNC CenterLine( unsigned argData,
  8416. %@AS@%                      ARG _far *pArg,
  8417. %@AS@%                      flagType fMeta )
  8418. %@AS@%  {
  8419. %@AS@%     PFILE pFile;
  8420. %@AS@%     LINE  yStart, yEnd;
  8421. %@AS@%     int   len;
  8422. %@AS@%     char *pBuf, buf[BUFLEN];%@AE@%%@NL@%
  8423. %@NL@%
  8424. %@AS@%  /* Get a handle to the current file */
  8425. %@AS@%     pFile = FileNameToHandle( "", "" );
  8426. %@AS@%  
  8427. %@AS@%     /* Handle various argument types */
  8428. %@AS@%     switch( pArg->argType )
  8429. %@AS@%     {
  8430. %@AS@%        case NOARG:  /* No argument. Center current line */
  8431. %@AS@%           yStart = yEnd = pArg->arg.noarg.y;
  8432. %@AS@%           break;
  8433. %@AS@%  
  8434. %@AS@%        case LINEARG:  /*  Center range of lines */
  8435. %@AS@%           yStart = pArg->arg.linearg.yStart;
  8436. %@AS@%           yEnd = pArg->arg.linearg.yEnd;
  8437. %@AS@%           break;
  8438. %@AS@%     }
  8439. %@AS@%  
  8440. %@AS@%     /* Center current line or range of lines */
  8441. %@AS@%     for( ; yStart <= yEnd; yStart++ )
  8442. %@AS@%     {
  8443. %@AS@%        /* Get a line from the current file */
  8444. %@AS@%        len = GetLine( yStart, buf, pFile );
  8445. %@AS@%  
  8446. %@AS@%        if( len > 0 )
  8447. %@AS@%        {
  8448. %@AS@%           /* Center the text in this line */
  8449. %@AS@%           pBuf = buf + strspn( buf, " \t" );
  8450. %@AS@%           len = strlen( pBuf );
  8451. %@AS@%           memmove( buf+(LINE_LENGTH-len) / 2, pBuf, len+1 );
  8452. %@AS@%           memset( buf, ' ', (LINE_LENGTH - len) / 2 );
  8453. %@AS@%  
  8454. %@AS@%           /* Write modified line back to the current file */
  8455. %@AS@%           PutLine( yStart, buf, pFile );
  8456. %@AS@%        }
  8457. %@AS@%     }
  8458. %@AS@%     return TRUE;
  8459. %@AS@%  }%@AE@%%@NL@%
  8460. %@NL@%
  8461. Building and using a PWB extension involves four basic steps:%@CR:C6A00080017 @%  %@NL@%
  8462. %@NL@%
  8463. %@NL@%
  8464.   1.  Compiling%@NL@%
  8465. %@NL@%
  8466.   2.  Linking%@NL@%
  8467. %@NL@%
  8468.   3.  Loading the extension into PWB%@NL@%
  8469. %@NL@%
  8470.   4.  Assigning a keystroke to each function in the extension%@NL@%
  8471. %@NL@%
  8472. %@NL@%
  8473. You can build extensions for both real mode (DOS) and OS/2 protected mode.  %@NL@%
  8474. %@NL@%
  8475. %@NL@%
  8476. %@3@%%@CR:C6A00080018 @%%@AB@%8.4.1  Building Real-Mode Extensions%@AE@%%@EH@%%@NL@%
  8477. %@NL@%
  8478. This section describes how to build extensions for real mode.%@CR:C6A00080019 @%  %@NL@%
  8479. %@NL@%
  8480. %@NL@%
  8481. %@4@%%@AB@%Compiling%@AE@%%@EH@%%@NL@%
  8482. %@NL@%
  8483. The source (.C) file for an extension must include EXT.H, the extension
  8484. header file. Since an extension is not a stand-alone executable file, it
  8485. doesn't have a %@AB@%main%@AE@% function; so its source file is compiled with the /c
  8486. (compile, but don't link) option:  %@NL@%
  8487. %@NL@%
  8488. %@AS@%  CL /c /Gs /ACw CENTER.C%@AE@%%@NL@%
  8489. %@NL@%
  8490. The /Gs option turns off stack checking; the /ACw option selects the
  8491. required custom memory model.  %@NL@%
  8492. %@NL@%
  8493. PWB extension interface is designed for C programmers. However, you can
  8494. write extensions in assembly language or other languages if you simulate the
  8495. required C memory model (in which SS is not assumed to equal DS).  %@NL@%
  8496. %@NL@%
  8497. %@NL@%
  8498. %@4@%%@AB@%Linking%@AE@%%@EH@%%@NL@%
  8499. %@NL@%
  8500. The first object file in the link command must be the stub EXTHDR.OBJ:  %@NL@%
  8501. %@NL@%
  8502. %@AS@%  link exthdr center, center.mxt;%@AE@%%@NL@%
  8503. %@NL@%
  8504. PWB can load a file with any name, but most programmers use the .MXT
  8505. extension to distinguish a PWB extension from a normal .EXE file.  %@NL@%
  8506. %@NL@%
  8507. %@NL@%
  8508. %@4@%%@AB@%Loading the Extension%@AE@%%@EH@%%@NL@%
  8509. %@NL@%
  8510. Once the extension is built, you can cause PWB to load it by adding a %@AB@%load%@AE@%
  8511. command to your TOOLS.INI file:  %@NL@%
  8512. %@NL@%
  8513. %@AS@%  load:center%@AE@%%@NL@%
  8514. %@NL@%
  8515. You don't need to supply a file extension; PWB assumes the correct file
  8516. extension. To specify a path, supply the path name preceded by a dollar sign
  8517. ($):  %@NL@%
  8518. %@NL@%
  8519. %@AS@%  load:$INIT:center%@AE@%%@NL@%
  8520. %@NL@%
  8521. The example tells PWB to search the directories specified in the INIT
  8522. environment variable. If listed, the environment variable must be in
  8523. uppercase.  %@NL@%
  8524. %@NL@%
  8525. TOOLS.INI can contain multiple %@AB@%load%@AE@% commands for different extensions.
  8526. However, loading each extension involves a certain amount of memory
  8527. overhead, and there is no way to unload an extension from memory. To
  8528. conserve memory, place all frequently used functions in a single extension
  8529. and load only that extension.%@CR:C6A00080020 @%  %@NL@%
  8530. %@NL@%
  8531. %@NL@%
  8532. %@4@%%@AB@%Assigning Keystrokes to Functions%@AE@%%@EH@%%@NL@%
  8533. %@NL@%
  8534. After an extension has been loaded, you must provide some way to invoke its
  8535. functions from inside PWB. A keystroke is the most common means, although
  8536. extension functions, like native PWB functions, can be invoked in various
  8537. ways.  %@NL@%
  8538. %@NL@%
  8539. You can assign the ALT+C keystroke to the %@AS@% CenterLine %@AE@% function with:  %@NL@%
  8540. %@NL@%
  8541. %@AS@%  CenterLine:alt+c%@AE@%%@NL@%
  8542. %@NL@%
  8543. Once the %@AS@% CenterLine %@AE@% function has been assigned to this keystroke, you can
  8544. invoke it by pressing ALT+C.  %@NL@%
  8545. %@NL@%
  8546. %@NL@%
  8547. %@3@%%@CR:C6A00080021 @%%@AB@%8.4.2  Building Protected-Mode Extensions%@AE@%%@EH@%%@NL@%
  8548. %@NL@%
  8549. The build process for OS/2 protected mode differs only slightly from the
  8550. real-mode build process.%@CR:C6A00080022 @%  %@NL@%
  8551. %@NL@%
  8552. %@NL@%
  8553. %@4@%%@AB@%Compiling%@AE@%%@EH@%%@NL@%
  8554. %@NL@%
  8555. The source (.C) file for an extension must include EXT.H, the extension
  8556. header file. Since an extension is not a stand-alone executable file, it
  8557. doesn't have a %@AB@%main%@AE@% function; so its source file is compiled with the /c
  8558. (compile, but don't link) option:  %@NL@%
  8559. %@NL@%
  8560. %@AS@%  CL /c /Gs /ACw CENTER.C%@AE@%%@NL@%
  8561. %@NL@%
  8562. The /Gs option turns off stack checking; the /ACw option selects the
  8563. required custom memory model.  %@NL@%
  8564. %@NL@%
  8565. PWB extension interface is designed for C programmers. However, you can
  8566. write extensions in assembly language or other languages if you simulate the
  8567. required C memory model (in which SS is not assumed to equal DS).  %@NL@%
  8568. %@NL@%
  8569. %@NL@%
  8570. %@4@%%@AB@%Linking%@AE@%%@EH@%%@NL@%
  8571. %@NL@%
  8572. Link with EXTHRDP.OBJ instead of EXTHDR.OBJ. Specify the .PXT extension for
  8573. the output file. List the EXT.DEF definitions file:  %@NL@%
  8574. %@NL@%
  8575. %@AS@%  link exthdrp center, center.pxt,, os2, ext.def%@AE@%%@NL@%
  8576. %@NL@%
  8577. %@NL@%
  8578. %@4@%%@AB@%Loading the Extension%@AE@%%@EH@%%@NL@%
  8579. %@NL@%
  8580. In protected mode, PWB assumes the .PXT file extension. If your extension is
  8581. not found, PWB assumes the .DLL file extension.%@CR:C6A00080023 @%  %@NL@%
  8582. %@NL@%
  8583. %@AU@% You cannot create a bound extension.%@AE@%  %@NL@%
  8584. %@NL@%
  8585. There is no way to create a bound extension (one that runs in both real and
  8586. protected mode). However, you can build separate versions of an extension
  8587. and use a single TOOLS.INI %@AB@%load%@AE@% command to load the correct extension in
  8588. each mode. PWB loads the real-mode file (.MXT) in real mode and the
  8589. protected-mode file (.PXT or .DLL) in protected mode.  %@NL@%
  8590. %@NL@%
  8591. %@NL@%
  8592. %@4@%%@AB@%Assigning Keystrokes to Functions%@AE@%%@EH@%%@NL@%
  8593. %@NL@%
  8594. After an extension has been loaded, you must provide some way to invoke its
  8595. functions from inside PWB. A keystroke is the most common means, although
  8596. extension functions, like native PWB functions, can be invoked in various
  8597. ways.  %@NL@%
  8598. %@NL@%
  8599. You can assign the ALT+C keystroke to the %@AS@% CenterLine %@AE@% function with:  %@NL@%
  8600. %@NL@%
  8601. %@AS@%  CenterLine:alt+c%@AE@%%@NL@%
  8602. %@NL@%
  8603. Once the %@AS@% CenterLine %@AE@% function has been assigned to this keystroke, you can
  8604. invoke it by pressing ALT+C.  %@NL@%
  8605. %@NL@%
  8606. %@NL@%
  8607. %@3@%%@CR:C6A00080024 @%%@AB@%8.4.3  Describing Functions and Switches%@AE@%%@EH@%%@NL@%
  8608. %@NL@%
  8609. To call functions in your extension, PWB must know certain information about
  8610. each function, such as the name and address of the function, what types of
  8611. arguments it accepts, and what switches (if any) it employs. You provide
  8612. this information in a pair of arrays─%@AB@%cmdTable%@AE@% and %@AB@%swiTable%@AE@%─that must be
  8613. present in every PWB extension.%@CR:C6A00080025 @%  %@NL@%
  8614. %@NL@%
  8615. %@NL@%
  8616. %@4@%%@AB@%The cmdTable Array%@AE@%%@EH@%%@NL@%
  8617. %@NL@%
  8618. Every extension must contain an array of structures named %@AB@%cmdTable%@AE@%. This
  8619. array provides the information PWB needs to call the extension's functions.
  8620. %@NL@%
  8621. %@NL@%
  8622. The %@AB@%cmdTable%@AE@% array is an array of structures of type %@AB@%cmdDesc%@AE@% (which is
  8623. declared in EXT.H). Each structure in the array describes one function in
  8624. the extension. The array is terminated with a structure whose members are
  8625. all null.  %@NL@%
  8626. %@NL@%
  8627. For instance, the CENTER.C extension has one function, named %@AS@% CenterLine%@AE@%, so
  8628. its %@AB@%cmdTable%@AE@% array contains two structures (one for %@AS@% CenterLine %@AE@% and the
  8629. other to terminate the table):%@CR:C6A00080026 @%  %@NL@%
  8630. %@NL@%
  8631. %@AS@%  struct cmdDesc cmdTable[] =
  8632. %@AS@%  {
  8633. %@AS@%     { "CenterLine", CenterLine, 0, NOARG | LINEARG },
  8634. %@AS@%     { NULL, NULL, 0, 0 }
  8635. %@AS@%  };%@AE@%%@NL@%
  8636. %@NL@%
  8637. Each %@AB@%cmdDesc%@AE@% structure in %@AB@%cmdTable%@AE@% contains these members:  %@NL@%
  8638. %@NL@%
  8639. %@NL@%
  8640.   ■   The function's name%@NL@%
  8641. %@NL@%
  8642.   ■   The function's address%@NL@%
  8643. %@NL@%
  8644.   ■   Reserved item (must be 0)%@NL@%
  8645. %@NL@%
  8646.   ■   The argument types the function accepts%@NL@%
  8647. %@NL@%
  8648. %@NL@%
  8649. The last member in the list is an integer containing bitflags representing
  8650. types of arguments that your function accepts. You can combine more than one
  8651. bitflag using the %@AB@%OR%@AE@% (%@AB@% | %@AE@%) operator.  %@NL@%
  8652. %@NL@%
  8653. For instance, the %@AS@% CenterLine %@AE@% function can handle an argument of the type
  8654. %@AB@%LINEARG%@AE@%, or no arguments (%@AB@%NOARG%@AE@%). So it lists the types:  %@NL@%
  8655. %@NL@%
  8656. %@AS@%  NOARG | LINEARG%@AE@%%@NL@%
  8657. %@NL@%
  8658. There are many argument types in addition to these. For information about
  8659. specific argument types, see the Extensions topic in on-line help.  %@NL@%
  8660. %@NL@%
  8661. %@NL@%
  8662. %@4@%%@AB@%The swiTable Array%@AE@%%@EH@%%@NL@%
  8663. %@NL@%
  8664. Extension functions, such as native PWB functions, can respond to user-
  8665. configurable switches. From the viewpoint of an extension function, a switch
  8666. is usually a variable that the user can change at run time. Your function
  8667. must be ready to respond to these changes, and PWB must have some way to
  8668. convey them. The vehicle for this interchange is an array of structures
  8669. named %@AB@%swiTable%@AE@%.  %@NL@%
  8670. %@NL@%
  8671. The %@AB@%swiTable%@AE@% array is similar to the %@AB@%cmdTable%@AE@% array described above. It is
  8672. an array of structures, terminated by a structure whose members are all
  8673. null. Each structure in %@AB@%swiTable%@AE@% describes one switch used by a function in
  8674. your extension.  %@NL@%
  8675. %@NL@%
  8676. The CENTER.C extension doesn't take any switches, so its %@AB@%swiTable%@AE@% array only
  8677. contains a terminating null structure:%@CR:C6A00080027 @%  %@NL@%
  8678. %@NL@%
  8679. %@AS@%  struct swiDesc swiTable[] =
  8680. %@AS@%  {
  8681. %@AS@%      { NULL, NULL, 0 }
  8682. %@AS@%  };%@AE@%%@NL@%
  8683. %@NL@%
  8684. Each structure in %@AB@%swiTable%@AE@% is of type %@AB@%swiDesc%@AE@%, whose members are  %@NL@%
  8685. %@NL@%
  8686. %@NL@%
  8687.   ■   A pointer to the switch name%@NL@%
  8688. %@NL@%
  8689.   ■   A pointer to the switch or a function%@NL@%
  8690. %@NL@%
  8691.   ■   A flag that indicates the type of the switch%@NL@%
  8692. %@NL@%
  8693. %@NL@%
  8694. A switch can be one of three types: %@AB@%SWI_BOOLEAN%@AE@% for TRUE/FALSE conditions,
  8695. %@AB@%SWI_NUMERIC%@AE@% for numerics, or %@AB@%SWI_SPECIAL%@AE@% for strings.  %@NL@%
  8696. %@NL@%
  8697. The second member of %@AB@%swiDesc%@AE@% is a pointer. It points to the switch itself if
  8698. the switch is type %@AB@%SWI_BOOLEAN%@AE@% or %@AB@%SWI_NUMERIC%@AE@%, or to a string-handling
  8699. function if the switch is type %@AB@%SWI_SPECIAL%@AE@%.  %@NL@%
  8700. %@NL@%
  8701. For instance, the following code creates a numeric switch with the default
  8702. value 27:  %@NL@%
  8703. %@NL@%
  8704. %@AS@%  static int n = 27;
  8705. %@AS@%  
  8706. %@AS@%  struct swiDesc swiTable[] =
  8707. %@AS@%  {
  8708. %@AS@%     { "newswitch", &n, SWI_NUMERIC | RADIX10 },
  8709. %@AS@%     { NULL,  NULL, 0 }
  8710. %@AS@%  };%@AE@%%@NL@%
  8711. %@NL@%
  8712. The first structure in the example above contains the name of the switch
  8713. (%@AS@%"newswitch"%@AE@%), a pointer to the variable that contains the switch's value
  8714. (%@AS@%&n%@AE@%), and the switch's type (%@AB@%SWI_NUMERIC%@AE@%).  %@NL@%
  8715. %@NL@%
  8716. In this example, the third structure member contains another constant,
  8717. %@AB@%RADIX10%@AE@%. If a switch is type %@AB@%SWI_NUMERIC%@AE@%, you must supply a second constant
  8718. to tell PWB whether to interpret user-assigned values as decimal (%@AB@%RADIX10%@AE@%)
  8719. or hexadecimal (%@AB@%RADIX16%@AE@%) numbers.  %@NL@%
  8720. %@NL@%
  8721. If the switch is type %@AB@%SWI_SPECIAL%@AE@%, the second member of %@AB@%swiDesc%@AE@% is a pointer
  8722. to an additional string-handling function that you write. This function must
  8723. be of type %@AB@%int far _pascal%@AE@%. Each time the text switch changes, PWB calls
  8724. your function, passing it the address of the updated string as a %@AB@%char far%@AE@%
  8725. pointer. The following code stores the updated string in a buffer named %@AS@%
  8726. %@AS@%mystring%@AE@%:%@CR:C6A00080028 @%  %@NL@%
  8727. %@NL@%
  8728. %@AS@%  char mystring[BUFLEN];
  8729. %@AS@%  
  8730. %@AS@%  int far _pascal setstr( char far *ptr )
  8731. %@AS@%  {
  8732. %@AS@%     strcpy( mystring, ptr );
  8733. %@AS@%  }%@AE@%%@NL@%
  8734. %@NL@%
  8735. If desired, you can list switches for extension functions separately from
  8736. other switches. Whenever PWB loads an extension, it looks in TOOLS.INI for a
  8737. section with this form:  %@NL@%
  8738. %@NL@%
  8739. %@AS@%  [PWB-ext]%@AE@%%@NL@%
  8740. %@NL@%
  8741. where %@AI@%ext%@AE@% is the base name of the extension. If the extension exists, PWB
  8742. recognizes the settings immediately following the tag. For instance, if your
  8743. extension SAMPLE.MXT uses a numeric switch named %@AS@% numbills%@AE@%, you can set %@AS@%
  8744. %@AS@%numbills %@AE@% to the value 66 with:  %@NL@%
  8745. %@NL@%
  8746. %@AS@%  [PWB-SAMPLE]
  8747. %@AS@%  numbills:66%@AE@%%@NL@%
  8748. %@NL@%
  8749. %@NL@%
  8750. %@3@%%@CR:C6A00080029 @%%@AB@%8.4.4  Initializing Functions%@AE@%%@EH@%%@NL@%
  8751. %@NL@%
  8752. Every PWB extension must contain a function named %@AB@%WhenLoaded%@AE@%, which PWB
  8753. calls immediately after loading the extension. The %@AB@%WhenLoaded%@AE@% function
  8754. provides a chance to do any initialization that your functions require. (If
  8755. your functions don't need any initialization, they can simply return.)  %@NL@%
  8756. %@NL@%
  8757. The CENTER.C extension uses %@AB@%WhenLoaded%@AE@% to display a loading message:%@CR:C6A00080030 @%%@CR:C6A00080031 @%%@CR:C6A00080032 @%  %@NL@%
  8758. %@NL@%
  8759. %@AS@%  void EXTERNAL WhenLoaded( void )
  8760. %@AS@%  {
  8761. %@AS@%      DoMessage( "Loading Center extension" );
  8762. %@AS@%  }%@AE@%%@NL@%
  8763. %@NL@%
  8764. %@AB@%DoMessage%@AE@% is a PWB function that displays a message on the dialog line.
  8765. Section 8.4.7, "Calling PWB Functions," lists PWB functions and explains how
  8766. to call them.  %@NL@%
  8767. %@NL@%
  8768. %@NL@%
  8769. %@3@%%@CR:C6A00080033 @%%@AB@%8.4.5  Prototyping Functions%@AE@%%@EH@%%@NL@%
  8770. %@NL@%
  8771. To be called by PWB, each extension function must be declared as type
  8772. %@AB@%PWBFUNC%@AE@% and accept the parameters %@AB@%argData%@AE@%, %@AB@%pArg%@AE@%, and %@AB@%fMeta%@AE@%. The %@AS@% CenterLine
  8773. %@AS@%%@AE@%function in the section of CENTER.C code below follows  this model:  %@NL@%
  8774. %@NL@%
  8775. %@AS@%  PWBFUNC CenterLine( unsigned argData, 
  8776. %@AS@%                      ARG _far *pArg,
  8777. %@AS@%                      flagType fMeta )%@AE@%%@NL@%
  8778. %@NL@%
  8779. The %@AB@%PWBFUNC%@AE@% type is actually a macro that evaluates to %@AB@%flagType _pascal
  8780. %@AB@%_loadds _far%@AE@%. The %@AB@%flagType%@AE@% return type declares that the function returns
  8781. either TRUE (nonzero) or FALSE (zero). Your function should return a value
  8782. so that it can be used in a macro with conditionals. The modifiers %@AB@%_pascal%@AE@%,
  8783. %@AB@%_loadds%@AE@%, and %@AB@%_far%@AE@% specify the calling conventions PWB expects editor
  8784. functions to have.  %@NL@%
  8785. %@NL@%
  8786. %@NL@%
  8787. %@3@%%@CR:C6A00080034 @%%@AB@%8.4.6  Receiving Parameters%@AE@%%@EH@%%@NL@%
  8788. %@NL@%
  8789. Like native PWB functions, extension functions can receive parameters from
  8790. the user. The CENTER.C example allows you to select a range of lines to
  8791. center, for example. The selected range is passed as a parameter to the %@AS@%
  8792. %@AS@%CenterLine %@AE@% function.%@CR:C6A00080035 @%%@CR:C6A00080036 @%%@CR:C6A00080037 @%  %@NL@%
  8793. %@NL@%
  8794. Extension functions receive parameters in much the same way ordinary C
  8795. programs receive command-line parameters. In both cases, the parameters are
  8796. passed in a predefined data construct─%@AB@%argc%@AE@% and %@AB@%argv%@AE@% for a normal C program,
  8797. and the following parameters for an extension function:  %@NL@%
  8798. %@NL@%
  8799. %@AB@%Parameter%@AE@%                         %@AB@%Description%@AE@%
  8800. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8801. %@AB@%argData%@AE@%                           The keystroke used to invoke your 
  8802.                                   function
  8803.  
  8804. %@AB@%pArg%@AE@%                              A pointer to a structure containing 
  8805.                                   arguments passed to your function
  8806.  
  8807. %@AB@%fMeta%@AE@%                             TRUE (nonzero) if %@AB@%meta%@AE@% precedes the 
  8808.                                   argument, otherwise FALSE (zero)
  8809.  
  8810. The first parameter is rarely used. Most extension functions receive all
  8811. their parameter data in the second parameter, %@AB@%pArg%@AE@%. This parameter is a
  8812. pointer to a structure of type %@AB@%ARG%@AE@%, which contains:  %@NL@%
  8813. %@NL@%
  8814. %@AB@%Parameter%@AE@%                         %@AB@%Description%@AE@%
  8815. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8816. %@AB@%argType%@AE@%                           An integer that indicates the argument 
  8817.                                   type
  8818.  
  8819. %@AB@%arg%@AE@%                               A union of structures, one structure for
  8820.                                   each
  8821.                                   argument type
  8822.  
  8823. Typically, your function tests %@AB@%pArg->argType%@AE@% to find out what type of
  8824. parameter PWB has passed. Once the type is known, the function responds
  8825. accordingly. The following code from CENTER.C handles two argument types:%@CR:C6A00080038 @%  %@NL@%
  8826. %@NL@%
  8827. %@AS@%  switch( pArg->argType )
  8828. %@AS@%  {
  8829. %@AS@%     case NOARG:  /* No argument. Center current line */
  8830. %@AS@%        yStart = yEnd = pArg->arg.noarg.y;
  8831. %@AS@%        break;
  8832. %@AS@%  
  8833. %@AS@%     case LINEARG:  /*  Center range of lines */
  8834. %@AS@%        yStart = pArg->arg.linearg.yStart;
  8835. %@AS@%        yEnd = pArg->arg.linearg.yEnd;
  8836. %@AS@%        break;
  8837. %@AS@%  }%@AE@%%@NL@%
  8838. %@NL@%
  8839. %@AU@% PWB rejects invalid arguments.%@AE@%  %@NL@%
  8840. %@NL@%
  8841. If your function takes only one argument, it doesn't need to test
  8842. %@AB@%pArg->argType%@AE@% at all. PWB knows beforehand what argument types your function
  8843. accepts (via %@AB@%cmdDesc%@AE@%) and rejects any invalid arguments.  %@NL@%
  8844. %@NL@%
  8845. Once the argument type is known, your function can access the parameters
  8846. through %@AB@%pArg->arg%@AE@%, a structure whose members differ for each argument type.
  8847. In the %@AB@%NOARG%@AE@% (no arguments) case, it contains %@AI@%x%@AE@% and %@AI@%y%@AE@% values identifying the
  8848. cursor position in the current file:  %@NL@%
  8849. %@NL@%
  8850. %@AS@%  struct noargType
  8851. %@AS@%  {           /* no argument    */
  8852. %@AS@%     LINE y;  /* cursor line    */
  8853. %@AS@%     COL  x;  /* cursor column  */
  8854. %@AS@%  };%@AE@%%@NL@%
  8855. %@NL@%
  8856. The CENTER.C example uses the %@AI@%y%@AE@% value in this structure (%@AB@%noarg.y%@AE@%, the cursor
  8857. line) to center the current line:  %@NL@%
  8858. %@NL@%
  8859. %@AS@%  case NOARG:  /* No argument. Center current line */
  8860. %@AS@%     yStart = yEnd = pArg->arg.noarg.y;
  8861. %@AS@%     break;%@AE@%%@NL@%
  8862. %@NL@%
  8863. Similarly, in the %@AB@%LINEARG%@AE@% case, the %@AB@%pArg->arg%@AE@% structure contains three
  8864. values:  %@NL@%
  8865. %@NL@%
  8866. %@AS@%  struct lineargType
  8867. %@AS@%  {                /* line argument specified */
  8868. %@AS@%     int  cArg;    /* count of args pressed   */
  8869. %@AS@%     LINE yStart;  /* starting line of range  */
  8870. %@AS@%     LINE yEnd;    /* ending line of range    */
  8871. %@AS@%  };%@AE@%%@NL@%
  8872. %@NL@%
  8873. The CENTER.C example uses the starting and ending values in this structure
  8874. (%@AB@%yStart%@AE@% and %@AB@%yEnd%@AE@%) to center a range of selected lines:  %@NL@%
  8875. %@NL@%
  8876. %@AS@%  case LINEARG:  /*  Center range of lines */
  8877. %@AS@%     yStart = pArg->arg.linearg.yStart;
  8878. %@AS@%     yEnd = pArg->arg.linearg.yEnd;
  8879. %@AS@%     break;%@AE@%%@NL@%
  8880. %@NL@%
  8881. The method is the same for other argument types. The %@AB@%pArg->arg%@AE@% structures
  8882. for all argument types are described in on-line help.  %@NL@%
  8883. %@NL@%
  8884. %@NL@%
  8885. %@3@%%@CR:C6A00080039 @%%@AB@%8.4.7  Calling PWB Functions%@AE@%%@EH@%%@NL@%
  8886. %@NL@%
  8887. Many of PWB's internal functions are public. Your extension function can
  8888. call them for the same purposes that PWB itself does. This section
  8889. demonstrates the most commonly used PWB functions─those that manipulate the
  8890. current file.%@CR:C6A00080040 @%%@CR:C6A00080041 @%  %@NL@%
  8891. %@NL@%
  8892. A list of callable PWB functions appears near the end of this section. For
  8893. complete information on specific PWB functions, consult on-line help.  %@NL@%
  8894. %@NL@%
  8895. %@NL@%
  8896. %@4@%%@AB@%Getting a File Handle%@AE@%%@EH@%%@NL@%
  8897. %@NL@%
  8898. Extension functions can do many different tasks, but they typically
  8899. manipulate a file in some way. The extension function in the CENTER.C
  8900. example rewrites a line or lines in the current file, for example. The
  8901. current file is the one that appears in the editing window. Since it is
  8902. already open for editing, you can access the current file without opening
  8903. it. Simply assign its file handle to a variable in your function.  %@NL@%
  8904. %@NL@%
  8905. PWB file-handling functions use file handles of type %@AB@%PFILE%@AE@%. The CENTER.C
  8906. example declares the following handle variable:  %@NL@%
  8907. %@NL@%
  8908. %@AS@%  PFILE pFile;%@AE@%%@NL@%
  8909. %@NL@%
  8910. The %@AB@%FileNameToHandle%@AE@% function gets a handle to a file that is already open
  8911. for editing:  %@NL@%
  8912. %@NL@%
  8913. %@AS@%  pFile = FileNameToHandle( "", "" );%@AE@%%@NL@%
  8914. %@NL@%
  8915. The function takes two string arguments. If the first string is null, as
  8916. here, the %@AB@%FileNameToHandle%@AE@% function returns a handle to the current file.
  8917. You can use the %@AB@%AddFile%@AE@% function to get handles to other files (in which
  8918. case you may need to use other PWB functions such as %@AB@%FileRead%@AE@%).%@CR:C6A00080042 @%  %@NL@%
  8919. %@NL@%
  8920. %@NL@%
  8921. %@4@%%@AB@%Reading a Line From the File%@AE@%%@EH@%%@NL@%
  8922. %@NL@%
  8923. Once your function has a file handle, it can read from the file with the
  8924. %@AB@%GetLine%@AE@% function, which reads one line at a time:  %@NL@%
  8925. %@NL@%
  8926. %@AS@%  len = GetLine( yStart, buf, pFile );%@AE@%%@NL@%
  8927. %@NL@%
  8928. The first argument is a line number, the second a pointer to a buffer, and
  8929. the third a file handle. So the above call reads line number %@AS@% yStart %@AE@% from
  8930. the file whose handle is %@AS@% pFile %@AE@% into the buffer %@AS@% buf%@AE@%. Note that the first
  8931. line in a file is line 0, not line 1.  %@NL@%
  8932. %@NL@%
  8933. Once you have read a line into a local buffer, you can manipulate it as
  8934. desired. CENTER.C uses its buffer %@AS@% buf %@AE@% to center the line's text.  %@NL@%
  8935. %@NL@%
  8936. %@NL@%
  8937. %@4@%%@AB@%Writing a Line to the File%@AE@%%@EH@%%@NL@%
  8938. %@NL@%
  8939. After modifying a line, you can write it back to the file. The %@AB@%PutLine%@AE@%
  8940. function writes one line at a time:  %@NL@%
  8941. %@NL@%
  8942. %@AS@%  PutLine( yStart, buf, pFile );%@AE@%%@NL@%
  8943. %@NL@%
  8944. %@AB@%PutLine%@AE@% takes the same arguments as %@AB@%GetLine%@AE@%─a line number, buffer pointer,
  8945. and file handle. In CENTER.C, the above call writes the line from %@AS@% buf %@AE@% to
  8946. line %@AS@% %@AE@%yStart  in the file whose handle is %@AS@% pFile%@AE@%.  %@NL@%
  8947. %@NL@%
  8948. %@NL@%
  8949. %@4@%%@AB@%Summary of PWB Functions%@AE@%%@EH@%%@NL@%
  8950. %@NL@%
  8951. If you understand how CENTER.C works, you know the basics of using PWB
  8952. functions in your own functions. The rest is just a matter of learning the
  8953. details of individual functions. Table 8.1 lists the PWB functions, grouping
  8954. them by category. For additional information on specific functions, consult
  8955. on-line help.%@CR:C6A00080043 @%  %@NL@%
  8956. %@NL@%
  8957. %@AB@%Table 8.1  %@AB@%Callable PWB Functions%@AE@%%@AE@%
  8958.  
  8959. %@TH:  50  2028 02 19 19 38 @%
  8960. Category           Function           Description
  8961. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8962. Block Operations   %@AB@%CopyBox%@AE@%            Insert rectangular area
  8963.  
  8964.                    %@AB@%CopyLine%@AE@%           Insert range of lines
  8965.  
  8966.                    %@AB@%CopyStream%@AE@%         Insert stream of text
  8967.  
  8968.                    %@AB@%DelBox%@AE@%             Delete rectangular area
  8969.  
  8970.                    %@AB@%DelLine%@AE@%            Delete range of lines
  8971.  
  8972.                    %@AB@%DelStream%@AE@%          Delete stream of text
  8973.  
  8974. Build              %@AB@%fGetMake%@AE@%           Get %@AB@%extmake%@AE@% setting
  8975.  
  8976.                    %@AB@%fSetMake%@AE@%           Set %@AB@%extmake%@AE@% setting
  8977.  
  8978. Color              %@AB@%GetColor%@AE@%           Get color of specified line
  8979.  
  8980.                    %@AB@%PutColor%@AE@%           Set color of specified line
  8981.  
  8982. Cursor             %@AB@%GetCursor%@AE@%          Get cursor position
  8983.  
  8984.                    %@AB@%MoveCur%@AE@%            Move cursor
  8985.  
  8986. Dialog             %@AB@%DoMessageBox%@AE@%       Create message dialog
  8987.  
  8988.                    %@AB@%PopUpBox%@AE@%           Display text in dialog 
  8989.                                       window
  8990.  
  8991. Display            %@AB@%BadArg%@AE@%             Report that argument was invalid
  8992.  
  8993.                    %@AB@%Display%@AE@%            Update screen
  8994.  
  8995.                    %@AB@%DoMessage%@AE@%          Display message on dialog line
  8996.  
  8997. File               %@AB@%AddFile%@AE@%            Open new file and get file handle
  8998.  
  8999.                    %@AB@%DelFile %@AE@%           Delete contents of file buffer
  9000.  
  9001.                    %@AB@%fChangeFile%@AE@%        Change current file to named file
  9002.  
  9003.                    %@AB@%FileNameToHandle%@AE@%   Get handle to open file
  9004.  
  9005.                    %@AB@%FileRead%@AE@%           Copy disk file to file 
  9006.                                       buffer
  9007.  
  9008.                    %@AB@%FileWrite%@AE@%          Copy file buffer to disk file
  9009.  
  9010. %@TE:  50  2028 02 19 19 38 @%
  9011.  
  9012. %@AB@%Table 8.1  %@AB@% (continued)%@AE@%%@AE@%
  9013.  
  9014. %@TH:  71  2738 02 17 18 41 @%
  9015. Category         Function          Description
  9016. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9017.                  %@AB@%pFileToTop%@AE@%        Make specified file the current file
  9018.  
  9019.                  %@AB@%RemoveFile%@AE@%        Remove file from memory
  9020.  
  9021. Keyboard         %@AB@%KbHook %@AE@%           Restore keyboard control to PWB%@CR:C6A00080044 @%
  9022.  
  9023.                  %@AB@%KbUnHook%@AE@%          Remove keyboard control from PWB
  9024.  
  9025.                  %@AB@%ReadChar%@AE@%          Get information on next keystroke
  9026.  
  9027. Format           %@AB@%ReadCmd%@AE@%           Get keystroke information in %@AB@%CmdDesc%@AE@%
  9028.  
  9029. Line             %@AB@%FileLength%@AE@%        Get length of file
  9030.  
  9031.                  %@AB@%GetLine%@AE@%           Get line from file
  9032.  
  9033.                  %@AB@%PutLine%@AE@%           Write line to file
  9034.  
  9035. List             %@AB@%GetListEntry%@AE@%      Get item from list
  9036.  
  9037.                  %@AB@%ScanList%@AE@%          Process list
  9038.  
  9039. Memory           %@AB@%Falloc%@AE@%            Allocate far memory
  9040.  
  9041.                  %@AB@%Fdalloc%@AE@%           Deallocate far memory
  9042.  
  9043. Miscellaneous    %@AB@%fExecute%@AE@%          Execute macro
  9044.  
  9045.                  %@AB@%FindSwitch%@AE@%        Get information about switch
  9046.  
  9047.                  %@AB@%GetEditorObject%@AE@%   Get internal PWB data item
  9048.  
  9049.                  %@AB@%GetString%@AE@%         Get input from dialog line
  9050.  
  9051.                  %@AB@%mgetenv%@AE@%           Get environment string
  9052.  
  9053.                  %@AB@%NameToFunc%@AE@%        Get information about function or macro
  9054.  
  9055.                  %@AB@%NameToKeys%@AE@%        Get key(s) assigned to specified 
  9056.                                    function
  9057.  
  9058.                  %@AB@%Replace%@AE@%           Replace character
  9059.  
  9060.                  %@AB@%SetEditorObject%@AE@%   Set internal PWB data item
  9061.  
  9062.                  %@AB@%SetKey%@AE@%            Assign function to 
  9063.                                    keystroke
  9064.  
  9065. Search           %@AB@%REsearch%@AE@%          Search for regular 
  9066.                                    expression
  9067.  
  9068.                  %@AB@%search%@AE@%            Search for string
  9069.  
  9070. Virtual Memory   %@AB@%fpbtoVM%@AE@%           Copy data to virtual memory
  9071.  
  9072.                  %@AB@%VMalloc%@AE@%           Allocate virtual memory
  9073.  
  9074.                  %@AB@%VMFree%@AE@%            Free virtual memory
  9075.  
  9076.                  %@AB@%VMtofpb%@AE@%           Copy data from virtual memory
  9077.  
  9078. Window           %@AB@%CloseWnd%@AE@%          Close window
  9079.  
  9080.                  %@AB@%Resize%@AE@%            Resize window
  9081.  
  9082.                  %@AB@%SplitWnd%@AE@%          Split window
  9083.  
  9084. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9085.  
  9086. %@TE:  71  2738 02 17 18 41 @%
  9087.  
  9088. %@CR:C6A00080045 @%%@NL@%
  9089. %@3@%%@CR:C6A00080046 @%%@AB@%8.4.8  Calling C Library Functions%@AE@%%@EH@%%@NL@%
  9090. %@NL@%
  9091. You can write many useful extension functions using only PWB functions
  9092. listed in the previous section. It is also possible to call C library
  9093. routines, with some limitations. An extension written for OS/2 protected
  9094. mode can call any C library routine if it is linked with EXTHDRP.OBJ and the
  9095. .DLL C run-time library. The list of usable routines is shorter for
  9096. real-mode (DOS) extensions linked with the non-.DLL run-time library.%@CR:C6A00080047 @%  %@NL@%
  9097. %@NL@%
  9098. Before you call a C library routine, ask whether the task can be done with a
  9099. PWB function. If the answer is yes, you should always call a PWB function in
  9100. preference to the C library routine. This practice ensures compatibility
  9101. between your functions and PWB.  %@NL@%
  9102. %@NL@%
  9103. The following categories of C library routines are always safe to use in
  9104. real mode:  %@NL@%
  9105. %@NL@%
  9106. %@NL@%
  9107.   ■   Buffer manipulation%@NL@%
  9108. %@NL@%
  9109.   ■   Character classification and conversion%@NL@%
  9110. %@NL@%
  9111.   ■   Data conversion%@NL@%
  9112. %@NL@%
  9113.   ■   String manipulation%@NL@%
  9114. %@NL@%
  9115. %@NL@%
  9116. This list includes the library routines you are most likely to need in an
  9117. extension function. If your extension function calls C library functions,
  9118. you must link with the compact-model C library.  %@NL@%
  9119. %@NL@%
  9120. The following routines should not be used in real mode:  %@NL@%
  9121. %@NL@%
  9122. %@NL@%
  9123.   ■   Routines that need C start-up support (most input/output functions)%@NL@%
  9124. %@NL@%
  9125.   ■   Memory management routines, such as %@AB@%malloc%@AE@%, and routines that call
  9126.       them%@NL@%
  9127. %@NL@%
  9128.   ■   Process control routines such as %@AB@%spawn%@AE@% and %@AB@%exec%@AE@%%@NL@%
  9129. %@NL@%
  9130. %@NL@%
  9131. If you are in doubt about a particular C library routine, you can always use
  9132. it and see what happens. If the linker displays the following message,%@CR:C6A00080048 @%  %@NL@%
  9133. %@NL@%
  9134. %@AS@%  error L2044: __acrtused : symbol multiply defined, use /NOE%@AE@%%@NL@%
  9135. %@NL@%
  9136. the routine requires C start-up support and should not be used.  %@NL@%
  9137. %@NL@%
  9138. %@NL@%
  9139. %@NL@%
  9140. %@NL@%
  9141. %@NL@%
  9142. %@NL@%
  9143. %@CR:C6A00090001 @%%@1@%%@AB@%Chapter 9  Debugging C Programs with CodeView%@AE@%%@EH@%%@NL@%
  9144. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9145. %@NL@%
  9146. Even experienced programmers occasionally find bugs in their programs. This
  9147. chapter explores techniques that will help you locate these errors quickly,
  9148. using the Microsoft CodeView debugger.  %@NL@%
  9149. %@NL@%
  9150. This chapter describes:  %@NL@%
  9151. %@NL@%
  9152. %@NL@%
  9153.   ■   How to display and modify variables and memory%@NL@%
  9154. %@NL@%
  9155.   ■   How to control the flow of execution while debugging%@NL@%
  9156. %@NL@%
  9157.   ■   Advanced CodeView debugging techniques%@NL@%
  9158. %@NL@%
  9159.   ■   How to control CodeView's behavior with command-line switches and the
  9160.       TOOLS.INI file%@NL@%
  9161. %@NL@%
  9162. %@NL@%
  9163. CodeView supports the Microsoft mouse (or any fully compatible pointing
  9164. device). All operations are described first using the mouse; the keyboard
  9165. command follows.  %@NL@%
  9166. %@NL@%
  9167. For information about debugging OS/2 programs that use threads or processes,
  9168. see Chapter 15, "Creating OS/2 Multithread Applications."  %@NL@%
  9169. %@NL@%
  9170. %@NL@%
  9171. %@2@%%@CR:C6A00090002 @%%@AB@%9.1  Understanding CodeView Windows%@AE@%%@EH@%%@NL@%
  9172. %@NL@%
  9173. CodeView divides the screen into logically separate sections called windows,
  9174. so that a large amount of information can be displayed in an organized and
  9175. easy-to-read fashion. Each window is a discrete section of the display that
  9176. operates independently of the other windows.  %@NL@%
  9177. %@NL@%
  9178. %@AU@% Each window displays a different type of data.%@AE@%  %@NL@%
  9179. %@NL@%
  9180. Each CodeView window has a distinct function. The name of each window
  9181. described below appears in the top of the window's frame:  %@NL@%
  9182. %@NL@%
  9183. %@NL@%
  9184.   ■   The Source window displays the source code. You can open a second
  9185.       Source window to view an include file, another source file, or the
  9186.       same source file at a different location.%@NL@%
  9187. %@NL@%
  9188.   ■   The Command window accepts debugging commands.%@NL@%
  9189. %@NL@%
  9190.   ■   The Watch window displays the current values of selected variables.%@NL@%
  9191. %@NL@%
  9192.   ■   The Local window lists the values of all variables local to the
  9193.       current function or block.%@NL@%
  9194. %@NL@%
  9195.   ■   The Memory window shows the contents of memory. You can open a second
  9196.       Memory window to view a different section of memory.%@NL@%
  9197. %@NL@%
  9198.   ■   The Register window displays the contents of the microprocessor's
  9199.       registers, as well as the processor flags.%@NL@%
  9200. %@NL@%
  9201.   ■   The 8087 window displays the registers of the coprocessor or its
  9202.       software emulator.%@NL@%
  9203. %@NL@%
  9204. %@NL@%
  9205. CodeView starts running with three windows displayed. The Local window is at
  9206. the top, the Source window fills the middle of the screen, and the Command
  9207. window is at the bottom.  %@NL@%
  9208. %@NL@%
  9209. There are two ways to open windows. You can choose the desired window from
  9210. the View menu. (Note that you can open more than one of certain windows,
  9211. such as Source or Memory.) In addition, some operations (such as selecting a
  9212. Watch variable) open the appropriate window automatically, if it is not
  9213. already open.  %@NL@%
  9214. %@NL@%
  9215. %@AU@% All displays are  updated automatically.%@AE@%  %@NL@%
  9216. %@NL@%
  9217. CodeView continually and automatically updates the contents of all windows.
  9218. However, if you want to interact with a particular window (for instance, to
  9219. enter a command, set a breakpoint, or modify a variable), you must select
  9220. that window as the focus of user interaction.  %@NL@%
  9221. %@NL@%
  9222. The selected window is called the "current" window. The current window is
  9223. marked in three ways:  %@NL@%
  9224. %@NL@%
  9225. %@NL@%
  9226.   ■   The window's name is highlighted in white.%@NL@%
  9227. %@NL@%
  9228.   ■   The text cursor appears in the window.%@NL@%
  9229. %@NL@%
  9230.   ■   The vertical and horizontal scroll bars are moved into the window.%@NL@%
  9231. %@NL@%
  9232. %@NL@%
  9233. To select a new current window, click left in the window (position the mouse
  9234. cursor in the window and press the left mouse button) that you want to be
  9235. current. You can also press F6 or SHIFT+F6 to move the focus from one window
  9236. to the next.  %@NL@%
  9237. %@NL@%
  9238. Windows often contain more information than can be displayed in the area
  9239. allotted to the window. There are two ways to view these additional
  9240. contents. You can drag on the window's horizontal or vertical scroll bars.
  9241. (Position the mouse pointer on the bar and, while holding down the left
  9242. mouse button, drag the mouse in the appropriate direction.) You can also use
  9243. the direction keys (LEFT, RIGHT, UP, DOWN) to move the text cursor.  %@NL@%
  9244. %@NL@%
  9245. Typing commands into the Source window causes CodeView to temporarily shift
  9246. its focus to the Command window. Whatever you type is appended to the last
  9247. line in the Command window. If the Command window is closed, CodeView beeps
  9248. in response to your entry and ignores the input.  %@NL@%
  9249. %@NL@%
  9250. %@NL@%
  9251. %@4@%%@AB@%Adjusting the Windows%@AE@%%@EH@%%@NL@%
  9252. %@NL@%
  9253. Although you cannot change the relative positions of the windows, you can
  9254. change their size or remove them. The Maximize, Size, and Close commands
  9255. from the View menu perform these functions, or you can press CTRL+F10,
  9256. CTRL+F8, and CTRL+F4, respectively. Window manipulations are especially easy
  9257. with a mouse:  %@NL@%
  9258. %@NL@%
  9259. %@NL@%
  9260.   ■   To maximize a window (enlarge it so it fills the screen), click left
  9261.       on the up arrow at the right end of the window's top border. To
  9262.       restore the window to its previous size and position, click left on
  9263.       the double arrow at the right end of the top border.%@NL@%
  9264. %@NL@%
  9265.   ■   To change the size of a window, position the mouse pointer anywhere
  9266.       along the white line at the top of the window. Press and hold down the
  9267.       left mouse button. When two double arrows appear on the line, you can
  9268.       drag the mouse to enlarge or reduce the window. The same action on a
  9269.       vertical border widens or narrows the window.%@NL@%
  9270. %@NL@%
  9271.   ■   To close a window, click left on the dot at the left end of the top
  9272.       border. You can also close any window in the View menu whose name has
  9273.       a dot next to it by selecting that window from the menu or by pressing
  9274.       that window's acclerator key. The adjacent windows automatically
  9275.       expand to recover the empty space.%@NL@%
  9276. %@NL@%
  9277. %@NL@%
  9278. CodeView stores session information in a file called CURRENT.STS, which is
  9279. created in the directory pointed to by the INIT environment variable. The
  9280. session information includes such items as the name of the program being
  9281. debugged, which CodeView windows were open, and the breakpoint locations.
  9282. This information becomes the default status the next time you run CodeView.%@CR:C6A00090003 @%%@CR:C6A00090004 @%
  9283. %@NL@%
  9284. %@NL@%
  9285. %@NL@%
  9286. %@2@%%@CR:C6A00090005 @%%@AB@%9.2  Overview of Debugging Techniques%@AE@%%@EH@%%@NL@%
  9287. %@NL@%
  9288. There is no single best approach to debugging for all programs or users.
  9289. CodeView offers a variety of debugging tools that let you pick a method
  9290. appropriate to the program or your work habits. The following section  may
  9291. help you decide how to approach a particular program.  %@NL@%
  9292. %@NL@%
  9293. Broadly speaking, two things can go wrong in a program:  %@NL@%
  9294. %@NL@%
  9295. %@NL@%
  9296.   ■   The program doesn't manipulate the data the way you expected it to.%@NL@%
  9297. %@NL@%
  9298.   ■   The flow of execution is incorrect.%@NL@%
  9299. %@NL@%
  9300. %@NL@%
  9301. These problems occasionally overlap. Incorrect execution can corrupt the
  9302. data, and bad data can cause execution to take an unexpected turn. Because
  9303. CodeView allows you to trace program execution %@AI@%and%@AE@% display whatever
  9304. combination of variables you want simultaneously, you don't have to know
  9305. ahead of time whether the problem is bad data manipulation, a bad execution
  9306. path, or some combination of these.  %@NL@%
  9307. %@NL@%
  9308. CodeView has features that deal specifically with the problems of bad data
  9309. and incorrect execution:  %@NL@%
  9310. %@NL@%
  9311. %@NL@%
  9312.   ■   You can view and modify any program variable, any section of memory,
  9313.       or any processor register.%@NL@%
  9314. %@NL@%
  9315.   ■   You can monitor the path of execution and precisely control where
  9316.       execution pauses.%@NL@%
  9317. %@NL@%
  9318. %@NL@%
  9319. The following sections explain how to view and modify data and describe how
  9320. execution is controlled.  %@NL@%
  9321. %@NL@%
  9322. %@NL@%
  9323. %@2@%%@CR:C6A00090006 @%%@AB@%9.3  Viewing and Modifying Program Data%@AE@%%@EH@%%@NL@%
  9324. %@NL@%
  9325. The CodeView debugger offers a variety of ways to display program variables,
  9326. processor registers, and memory. You can also modify the values of all these
  9327. items as the program executes. This section shows how to display and modify
  9328. variables, registers, and memory.  %@NL@%
  9329. %@NL@%
  9330. %@NL@%
  9331. %@3@%%@CR:C6A00090007 @%%@AB@%9.3.1  Displaying Variables in the Watch Window%@AE@%%@EH@%%@NL@%
  9332. %@NL@%
  9333. To add a variable to the Watch window, position the cursor on the name of
  9334. the variable using either the mouse or the direction keys (LEFT, RIGHT, UP,
  9335. DOWN). Then select the Add Watch command from the Watch menu, or press
  9336. CTRL+W.  %@NL@%
  9337. %@NL@%
  9338. A dialog box appears with the selected variable's name displayed in the
  9339. Expression field. If you don't want to watch the variable shown, type in the
  9340. name of the variable you want to watch. Pressing ENTER or clicking left on
  9341. the OK button adds this variable to the Watch window.  %@NL@%
  9342. %@NL@%
  9343. The Watch window appears at the top of the screen. Adding a Watch variable
  9344. automatically opens the Watch window if the window doesn't already exist.  %@NL@%
  9345. %@NL@%
  9346. A newly added variable may be followed by the message:  %@NL@%
  9347. %@NL@%
  9348. %@AS@%  <Watch Expression Not in Context>%@AE@%%@NL@%
  9349. %@NL@%
  9350. This message appears when program execution has not yet reached the block
  9351. where the variable is defined. (A block is a section of code enclosed in
  9352. curly braces.) Global variables (those declared outside C functions) never
  9353. cause CodeView to display this message; they can be watched from anywhere in
  9354. the program.  %@NL@%
  9355. %@NL@%
  9356. To remove a variable from the Watch window, use the Delete Watch command
  9357. from the Watch menu, and select the variable to be removed using the list in
  9358. the dialog box. You can also position the cursor on any line in the Watch
  9359. window and press CTRL+Y to delete the line.  %@NL@%
  9360. %@NL@%
  9361. %@AU@% There is no limit to how many variables you can watch.%@AE@%  %@NL@%
  9362. %@NL@%
  9363. You can place as many variables as you like in the Watch window; the
  9364. quantity is limited only by available memory. You can scroll through the
  9365. Watch window to position it at those variables you want to view. CodeView
  9366. automatically updates all watched variables as the program runs, including
  9367. those not currently visible.  %@NL@%
  9368. %@NL@%
  9369. Loops (%@AB@%do%@AE@%, %@AB@%for%@AE@%, or %@AB@%while%@AE@%) cause problems when they don't terminate
  9370. correctly. Displaying loop variables in the Watch window is an easy way to
  9371. determine whether a loop variable achieves its proper value.  %@NL@%
  9372. %@NL@%
  9373. %@NL@%
  9374. %@3@%%@CR:C6A00090008 @%%@AB@%9.3.2  Displaying Expressions in the Watch Window%@AE@%%@EH@%%@NL@%
  9375. %@NL@%
  9376. You may have noticed that the Add Watch dialog box prompts for an
  9377. expression, not simply a variable name. As this suggests, you can enter an
  9378. expression (that is, any valid combination of variables, constants, and
  9379. operators) for CodeView to evaluate and display.  %@NL@%
  9380. %@NL@%
  9381. %@AU@% Expressions can use the  syntax of other languages.%@AE@%  %@NL@%
  9382. %@NL@%
  9383. You are not limited to evaluating C expressions. The Language command of the
  9384. Options menu offers a choice of BASIC or FORTRAN expression evaluation, if
  9385. one of these languages better suits your needs. The ability to select the
  9386. language evaluator is especially useful when debugging mixed-language
  9387. programs. Remember that C-specific features, such as type casting or pointer
  9388. conversions, are not available in other languages.  %@NL@%
  9389. %@NL@%
  9390. %@AU@% You can display more information with expressions than with individual
  9391. %@AU@%variables.%@AE@%  %@NL@%
  9392. %@NL@%
  9393. By reducing several variables to a single, easily read value, an expression
  9394. can be easier to interpret than the components that make it up. Imagine a
  9395. %@AB@%for%@AE@% loop with two variables whose ratio is supposed to remain constant. You
  9396. suspect that one of these variables (you aren't sure which) sometimes takes
  9397. the wrong value. With %@AS@%(var1 / var2) %@AE@% displayed as an expression in the Watch
  9398. window, you can easily see when this single value changes; you don't have to
  9399. mentally divide two numbers.  %@NL@%
  9400. %@NL@%
  9401. You can also display Boolean expressions. For example, if a variable is
  9402. never supposed to be larger than 100 or less than 25, %@AS@% (var < 25 || var >
  9403. %@AS@%100) %@AE@% evaluates to 1 (true) when %@AS@% var %@AE@% goes out-of-bounds.  %@NL@%
  9404. %@NL@%
  9405. %@NL@%
  9406. %@3@%%@CR:C6A00090009 @%%@AB@%9.3.3  Displaying Arrays and Structures%@AE@%%@EH@%%@NL@%
  9407. %@NL@%
  9408. Most program variables are scalar quantities─a single character or a single
  9409. integer or floating-point value. These appear in the Watch window with the
  9410. variable name to the left, followed by an equal sign (%@AB@%=%@AE@%) and the current
  9411. value.  %@NL@%
  9412. %@NL@%
  9413. %@AU@% You can view arrays and structures in expanded form.%@AE@%  %@NL@%
  9414. %@NL@%
  9415. Arrays and structures contain multiple values, arranged in one or more
  9416. layers. They are often referred to as "aggregate" data items. CodeView lets
  9417. you control how much of these variables is shown; that is, whether all,
  9418. part, or none of their internal structure is displayed.  %@NL@%
  9419. %@NL@%
  9420. An array initially appears in the Watch window in this form:  %@NL@%
  9421. %@NL@%
  9422. %@AS@%  +wordholder[]  = [...]%@AE@%%@NL@%
  9423. %@NL@%
  9424. The brackets indicate that this variable contains more than one element. The
  9425. plus sign (+) indicates that the variable has not yet been expanded to
  9426. display its components.  %@NL@%
  9427. %@NL@%
  9428. To expand the array, double-click anywhere on the line. You can also
  9429. position the cursor on the line and press ENTER. For example, if %@AS@% wordholder
  9430. %@AS@%%@AE@% is a six-character array containing the word "Basic," the Watch window
  9431. display changes to the following :  %@NL@%
  9432. %@NL@%
  9433. %@AS@%  -wordholder[]
  9434. %@AS@%     [0]  =  66 'B'
  9435. %@AS@%     [1]  =  97 'a'
  9436. %@AS@%     [2]  =  115 's'
  9437. %@AS@%     [3]  =  105 'i'
  9438. %@AS@%     [4]  =  99 'c'
  9439. %@AS@%     [5]  =  0 ''%@AE@%%@NL@%
  9440. %@NL@%
  9441. Note that both the individual character values and their ASCII decimal
  9442. equivalents are listed. The minus sign (-) indicates no further expansion is
  9443. possible. To contract the array, double-click on its line (or position the
  9444. cursor on the line and press ENTER) again.  %@NL@%
  9445. %@NL@%
  9446. If it is inconvenient to view a character array in this form, cast the
  9447. variable's name to a character pointer by placing %@AS@% (char *) %@AE@% in front of the
  9448. name. The character array is then displayed as a string delimited by
  9449. apostrophes.  %@NL@%
  9450. %@NL@%
  9451. You can display arrays with more than one dimension. Imagine a 5 x 5 integer
  9452. array named %@AS@% matrix%@AE@%, whose diagonal elements are the numbers 1 through 5 and
  9453. whose other elements are zero. Unexpanded, the array is displayed like this:
  9454. %@NL@%
  9455. %@NL@%
  9456. %@AS@%  +matrix[]  = [...]%@AE@%%@NL@%
  9457. %@NL@%
  9458. Double-clicking on %@AS@% matrix %@AE@% (or pressing ENTER) changes the display:  %@NL@%
  9459. %@NL@%
  9460. %@AS@%  -matrix[]
  9461. %@AS@%    +[0][]  =  [...]
  9462. %@AS@%    +[1][]  =  [...]
  9463. %@AS@%    +[2][]  =  [...]
  9464. %@AS@%    +[3][]  =  [...]
  9465. %@AS@%    +[4][]  =  [...]%@AE@%%@NL@%
  9466. %@NL@%
  9467. The actual values of the elements are not shown yet. You have to descend one
  9468. more level to see them. To view the elements of the third row of the array,
  9469. position the cursor anywhere on the fourth line and press ENTER:  %@NL@%
  9470. %@NL@%
  9471. %@AS@%  -matrix[]
  9472. %@AS@%    +[0][]  =  [...]
  9473. %@AS@%    +[1][]  =  [...]
  9474. %@AS@%    -[2][]
  9475. %@AS@%       [0]  = 0
  9476. %@AS@%       [1]  = 0
  9477. %@AS@%       [2]  = 3
  9478. %@AS@%       [3]  = 0
  9479. %@AS@%       [4]  = 0
  9480. %@AS@%    +[3][]  =  [...]
  9481. %@AS@%    +[4][]  =  [...]%@AE@%%@NL@%
  9482. %@NL@%
  9483. Expanding the fifth row of the array produces this display:  %@NL@%
  9484. %@NL@%
  9485. %@AS@%  -matrix[]
  9486. %@AS@%    +[0][]  =  [...]
  9487. %@AS@%    +[1][]  =  [...]
  9488. %@AS@%    -[2][]
  9489. %@AS@%       [0]  = 0
  9490. %@AS@%       [1]  = 0
  9491. %@AS@%       [2]  = 3
  9492. %@AS@%       [3]  = 0
  9493. %@AS@%       [4]  = 0
  9494. %@AS@%    +[3][]  =  [...]
  9495. %@AS@%    -[4][]
  9496. %@AS@%       [0]  = 0
  9497. %@AS@%       [1]  = 0
  9498. %@AS@%       [2]  = 0
  9499. %@AS@%       [3]  = 0
  9500. %@AS@%       [4]  = 5%@AE@%%@NL@%
  9501. %@NL@%
  9502. %@AU@% You can view individual elements instead of  the entire array.%@AE@%  %@NL@%
  9503. %@NL@%
  9504. Any element of an array (or structure) can be independently expanded or
  9505. contracted. If you only want to view one or two elements of a large array,
  9506. specify the particular array or structure elements in the Expression field
  9507. of the Add Watch dialog box; you need not display every element of the
  9508. variable.  %@NL@%
  9509. %@NL@%
  9510. %@AU@% You can dereference pointers.%@AE@%  %@NL@%
  9511. %@NL@%
  9512. You can dereference a pointer in the same way as you expand an array or
  9513. structure. The pointer address is displayed, followed by all the elements of
  9514. the variable to which the pointer currently refers. Multiple levels of
  9515. indirection (that is, pointers referencing other pointers) can be displayed
  9516. simultaneously.  %@NL@%
  9517. %@NL@%
  9518. %@NL@%
  9519. %@3@%%@CR:C6A00090010 @%%@AB@%9.3.4  Displaying Array Elements Dynamically%@AE@%%@EH@%%@NL@%
  9520. %@NL@%
  9521. You do not have to display every element of an array. If specific subscripts
  9522. are given, the corresponding element is displayed.  %@NL@%
  9523. %@NL@%
  9524. You can also specify a dynamic array element, which changes as some other
  9525. variable changes. For example, suppose that the loop variable %@AS@% p %@AE@% is a
  9526. subscript for the array variable %@AS@% catalogprice%@AE@%. The Watch window expression %@AS@%
  9527. %@AS@%catalogprice[p] %@AE@% displays only the array element currently specified by %@AS@%p%@AE@%,
  9528. not the entire array.  %@NL@%
  9529. %@NL@%
  9530. You can mix constant and variable subscripts. For example, the expression %@AS@%
  9531. %@AS@%bigarray[3][i] %@AE@% displays only the element in the third row of the array to
  9532. which the index variable %@AS@% i %@AE@% points.  %@NL@%
  9533. %@NL@%
  9534. %@NL@%
  9535. %@3@%%@CR:C6A00090011 @%%@AB@%9.3.5  Using Quick Watch%@AE@%%@EH@%%@NL@%
  9536. %@NL@%
  9537. Selecting the Quick Watch command from the Watch menu (or pressing SHIFT+F9)
  9538. displays the Quick Watch dialog box. If the text cursor is in the Source,
  9539. Local, or Watch window, the variable at the current cursor position appears
  9540. in the dialog box. If this is not the item you wish to display, type in the
  9541. desired expression or variable, then press ENTER. The selected item is
  9542. displayed immediately.  %@NL@%
  9543. %@NL@%
  9544. The Quick Watch display automatically expands arrays and structures to their
  9545. first level. For example, an array with three dimensions is expanded to the
  9546. first dimension. You can expand or contract an element just as you would in
  9547. the Watch window: position the cursor on the appropriate line and press
  9548. ENTER. If the array needs more lines than the Quick Watch window can
  9549. display, drag the mouse along the scroll bar, or press DOWN or PGDN to view
  9550. the rest of the array.  %@NL@%
  9551. %@NL@%
  9552. %@AU@% You can add Quick Watch variables to the Watch window.%@AE@%  %@NL@%
  9553. %@NL@%
  9554. If you decide to add a Quick Watch item to the Watch window, select the Add
  9555. Watch button. Arrays and structures appear in the Watch window expanded as
  9556. they were displayed in the Quick Watch box.  %@NL@%
  9557. %@NL@%
  9558. Quick Watch is a convenient way to take a quick look at a variable or
  9559. expression. Since only one Quick Watch variable can be viewed at a time, you
  9560. would not use Quick Watch for most of the variables you want to view.  %@NL@%
  9561. %@NL@%
  9562. %@NL@%
  9563. %@3@%%@CR:C6A00090012 @%%@AB@%9.3.6  Displaying Memory%@AE@%%@EH@%%@NL@%
  9564. %@NL@%
  9565. Selecting the Memory command from the View menu opens a Memory window. Up to
  9566. two Memory windows can be open at one time.  %@NL@%
  9567. %@NL@%
  9568. By default, memory is displayed as hexadecimal byte values, with 16 bytes
  9569. per line. At the end of each line is a second display of the same memory in
  9570. ASCII form. Values that correspond to printable ASCII characters (decimal 32
  9571. through 127) are displayed in that form. Values outside this range are shown
  9572. as periods.  %@NL@%
  9573. %@NL@%
  9574. %@AU@% You can display memory  values in any form.%@AE@%  %@NL@%
  9575. %@NL@%
  9576. Byte values are not always the most convenient way to view memory. If the
  9577. area of memory you're examining contains character strings or floating-point
  9578. values, you might prefer to view them in a directly readable form. The
  9579. Memory Window command of the Options menu displays a dialog box with a
  9580. variety of display options:  %@NL@%
  9581. %@NL@%
  9582. %@NL@%
  9583.   ■   ASCII characters%@NL@%
  9584. %@NL@%
  9585.   ■   Byte, word, or double-word binary values%@NL@%
  9586. %@NL@%
  9587.   ■   Signed or unsigned integer decimal values%@NL@%
  9588. %@NL@%
  9589.   ■   Short (32 bit), long (64 bit), or ten-byte (80 bit) floating-point
  9590.       values%@NL@%
  9591. %@NL@%
  9592. %@NL@%
  9593. You can also directly cycle through these display formats by pressing F3.  %@NL@%
  9594. %@NL@%
  9595. If a section of memory cannot be displayed as a valid floating-point number,
  9596. the number shown includes the characters %@AS@% NAN %@AE@% (not a number).  %@NL@%
  9597. %@NL@%
  9598. %@NL@%
  9599. %@4@%%@AB@%Displaying Variables with a Live Expression%@AE@%%@EH@%%@NL@%
  9600. %@NL@%
  9601. Section 9.3.4, "Displaying Array Elements Dynamically," explains how to
  9602. display a specific array element by adding the appropriate expression to the
  9603. Watch window. It is also possible to watch a particular memory area that
  9604. your program uses to store data in the Memory window. This CodeView display
  9605. feature is called a "live expression."  %@NL@%
  9606. %@NL@%
  9607. "Live" means that the area of memory displayed changes to reflect the value
  9608. of a pointer or subscript. For example, if %@AS@% buffer %@AE@% is an array and %@AS@% pbuf %@AE@%
  9609. is a pointer to that array, then %@AS@% *pbuf %@AE@% points to the array element
  9610. currently referenced. A live expression displays the section of memory
  9611. beginning with this element. If your program changes the value of %@AS@% pbuf%@AE@%,
  9612. CodeView dynamically adjusts the Memory window display.  %@NL@%
  9613. %@NL@%
  9614. Live expressions are displayed in a Memory window, not in the Watch window.
  9615. To create a live expression, select the Memory Window command of the Options
  9616. menu, then select the Live Expression check box. Enter the name of the
  9617. element you want to view. For example, if %@AS@% strgptr %@AE@% is a pointer to an array
  9618. of characters, and you want to see what it currently points at, enter %@AS@%
  9619. %@AS@%*strgptr%@AE@%. Then select the OK button or press ENTER to view that memory area.
  9620. %@NL@%
  9621. %@NL@%
  9622. A new Memory window opens. The first memory location in the window is the
  9623. first memory location of the live expression. The section of memory
  9624. displayed changes to the section the pointer currently references.  %@NL@%
  9625. %@NL@%
  9626. You can use the Memory Window command of the Options menu to display the
  9627. value of the live expression in a directly readable form. This is especially
  9628. convenient when the live expression represents strings or floating-point
  9629. values, which are difficult to interpret in hexadecimal form.  %@NL@%
  9630. %@NL@%
  9631. It is usually more convenient to view an item in the Watch window than as a
  9632. live expression. However, some items are more easily viewed as live
  9633. expressions. For example, you can examine what is currently on top of the
  9634. stack. Enter SS:SP as the live expression.  %@NL@%
  9635. %@NL@%
  9636. %@NL@%
  9637. %@3@%%@CR:C6A00090013 @%%@AB@%9.3.7  Displaying the Processor Registers%@AE@%%@EH@%%@NL@%
  9638. %@NL@%
  9639. Selecting the Register command from the View menu (or pressing F2) opens a
  9640. window on the right side of the screen. The current values of the
  9641. microprocessor's registers appear in this window.  %@NL@%
  9642. %@NL@%
  9643. At the bottom of the window is a group of mnemonics representing the
  9644. processor flags. When you first open the Register window, all values are
  9645. shown in normal-intensity video. Any subsequent changes are marked in
  9646. high-intensity video. For example, suppose the overflow flag is not set when
  9647. the Register window is first opened. The corresponding mnemonic is NV and it
  9648. appears in light gray. If the overflow flag is subsequently set, the
  9649. mnemonic changes to OV and appears in bright white.  %@NL@%
  9650. %@NL@%
  9651. Selecting the 386 Instructions command from the Options menu displays the
  9652. registers as 32-bit values, but only if your computer uses an 80386
  9653. processor, and only when running the real-mode version of CodeView.
  9654. Selecting this command a second time toggles back to a 16-bit display.  %@NL@%
  9655. %@NL@%
  9656. You can also display the registers of an 8087/287/387 coprocessor in a
  9657. separate window by selecting the 8087 command from the View menu. If your
  9658. program uses the coprocessor emulator, the emulated registers are displayed
  9659. instead.  %@NL@%
  9660. %@NL@%
  9661. %@NL@%
  9662. %@3@%%@CR:C6A00090014 @%%@AB@%9.3.8  Modifying the Values of Variables, Registers, and Memory%@AE@%%@EH@%%@NL@%
  9663. %@NL@%
  9664. You can easily change the values of variables, memory locations, or
  9665. registers displayed in the Watch, Local, Memory, Register, or 8087 windows.
  9666. Simply position the cursor at the value you want to change and edit it to
  9667. the appropriate value. If you change your mind, press ALT+BKSP to undo the
  9668. last change you made.  %@NL@%
  9669. %@NL@%
  9670. The starting address of each line of memory displayed is shown at the left
  9671. of the Memory window, in CS:IP form. Altering the address automatically
  9672. shifts the display to the corresponding section of memory. If that section
  9673. is not used by your program, memory locations are displayed as double
  9674. question marks (??).  %@NL@%
  9675. %@NL@%
  9676. %@AU@% Byte display form is different from other forms.%@AE@%  %@NL@%
  9677. %@NL@%
  9678. When you select Byte display from the Memory Window Options dialog box,
  9679. CodeView presents both a hexadecimal and an ASCII representation of the data
  9680. in memory. (Byte display is the default.) You can change data in memory
  9681. either by entering new hex values over the hexadecimal representation of
  9682. your data or by entering character values over the character representation.
  9683. %@NL@%
  9684. %@NL@%
  9685. To toggle a processor flag, click left on its mnemonic. You can also
  9686. position the cursor on a mnemonic, then press any key (except TAB or SPACE).
  9687. Repeat to restore the flag to its previous setting.  %@NL@%
  9688. %@NL@%
  9689. %@AU@% Be cautious when modifying memory or a register.%@AE@%  %@NL@%
  9690. %@NL@%
  9691. The effect of changing a register, flag, or memory location may vary from no
  9692. effect at all, to crashing the operating system. You should be cautious when
  9693. altering "machine-level" values; most of the items you would want to change
  9694. can be altered from the Watch window.  %@NL@%
  9695. %@NL@%
  9696. One instance where direct manipulation of register values can be valuable is
  9697. when you are debugging in-line assembly code. You can change register values
  9698. to test assumptions before making changes in your source code and
  9699. recompiling.  %@NL@%
  9700. %@NL@%
  9701. %@NL@%
  9702. %@2@%%@CR:C6A00090015 @%%@AB@%9.4  Controlling Execution%@AE@%%@EH@%%@NL@%
  9703. %@NL@%
  9704. There are two forms of program execution under CodeView:  %@NL@%
  9705. %@NL@%
  9706. %@NL@%
  9707.   ■   Continuous; the program executes until either a previously specified
  9708.       "breakpoint" has been reached or the program terminates normally.%@NL@%
  9709. %@NL@%
  9710.   ■   Single-step; the program pauses after each line of code has been
  9711.       executed. %@NL@%
  9712. %@NL@%
  9713. %@NL@%
  9714. Sections 9.4.1 and 9.4.2 explain how each form of execution works and the
  9715. most effective way to use each.  %@NL@%
  9716. %@NL@%
  9717. %@NL@%
  9718. %@3@%%@CR:C6A00090016 @%%@AB@%9.4.1  Continuous Execution%@AE@%%@EH@%%@NL@%
  9719. %@NL@%
  9720. Continuous execution lets you quickly execute the bug-free sections of code,
  9721. which would otherwise take a long time to execute a single step at a time.  %@NL@%
  9722. %@NL@%
  9723. The simplest form of continuous execution is to click right (position the
  9724. mouse pointer and press the right mouse button) anywhere on the line of code
  9725. you want to debug or examine in more detail. The program executes at full
  9726. speed up to the beginning of this line, then pauses. You can do the same
  9727. thing by positioning the text cursor on this line, then pressing F7.  %@NL@%
  9728. %@NL@%
  9729. You can also pause execution at a specific line of code with a "breakpoint."
  9730. There are several types of breakpoints. Breakpoints are explained in the
  9731. following section.  %@NL@%
  9732. %@NL@%
  9733. %@NL@%
  9734. %@4@%%@AB@%Selecting Breakpoint Lines%@AE@%%@EH@%%@NL@%
  9735. %@NL@%
  9736. %@AU@% Breakpoints can be  tied to lines of code.%@AE@%  %@NL@%
  9737. %@NL@%
  9738. You can skip over the parts of the program that you don't want to examine by
  9739. specifying one or more lines as "breakpoints." The program executes at full
  9740. speed up to the first breakpoint, then pauses. Pressing F5 continues program
  9741. execution up to the next breakpoint, and so on. (You can halt execution at
  9742. any time by pressing CTRL+BREAK or ALT+SYSRQ.)  %@NL@%
  9743. %@NL@%
  9744. %@AU@% There is no limit to the  number of breakpoints.%@AE@%  %@NL@%
  9745. %@NL@%
  9746. You can set as many breakpoints as you like (limited only by available
  9747. memory). There are several ways to set breakpoints:  %@NL@%
  9748. %@NL@%
  9749. %@NL@%
  9750.   ■   Double-click anywhere on the desired breakpoint line. The selected
  9751.       line is highlighted to show that it is a breakpoint. To remove the
  9752.       breakpoint, double-click on the line a second time.%@NL@%
  9753. %@NL@%
  9754.   ■   Position the cursor anywhere on the line at which you want execution
  9755.       to pause. Press F9 to select the line as a breakpoint. (CodeView
  9756.       highlights lines that have been selected as breakpoints.) Press F9 a
  9757.       second time to remove the breakpoint. %@NL@%
  9758. %@NL@%
  9759.   ■   Display the Set Breakpoint dialog box by selecting Set Breakpoint from
  9760.       the Watch menu. Choose one of the breakpoint options that permits a
  9761.       line ("location") to be specified. The line on which the text cursor
  9762.       currently rests is the default breakpoint line in the Location field.
  9763.       If this line is not the desired breakpoint, enter the line number
  9764.       desired. (The line number must begin with a period.) Use F9 or the
  9765.       Edit Breakpoints screen of the Watch menu to remove the breakpoint.%@NL@%
  9766. %@NL@%
  9767. %@NL@%
  9768. %@AU@% Not every line can  be a breakpoint.%@AE@%  %@NL@%
  9769. %@NL@%
  9770. A breakpoint line must be a program line that represents executable code.
  9771. You cannot select a blank line, a comment line, or a declaration line (such
  9772. as a variable declaration or a preprocessor statement) as a breakpoint.  %@NL@%
  9773. %@NL@%
  9774. A breakpoint can also be set at a function or an explicit address. To set a
  9775. breakpoint at a function, simply enter its name in the Set Breakpoint dialog
  9776. box. To set a breakpoint at an address, enter the address in CS:IP form.  %@NL@%
  9777. %@NL@%
  9778. ────────────────────────────────────────────────────────────────────────────%@NL@%
  9779. NOTE
  9780.  
  9781. %@AI@%By default, Microsoft compilers optimize your code. In the process of
  9782. %@AI@%optimization, some lines of code may be repositioned or reorganized for more
  9783. %@AI@%efficient execution. These changes can prevent CodeView from recognizing the
  9784. %@AI@%corresponding lines of source code as breakpoints. Therefore, it is a good
  9785. %@AI@%idea to disable optimization during development (use the /Od switch). You
  9786. %@AI@%can restore optimization once debugging is completed.%@AE@%%@NL@%
  9787. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  9788. %@NL@%
  9789. Once execution has paused, you can continue execution by pressing F5 or
  9790. clicking left on the <F5> button in the display.  %@NL@%
  9791. %@NL@%
  9792. %@NL@%
  9793. %@4@%%@AB@%Setting Breakpoint Values%@AE@%%@EH@%%@NL@%
  9794. %@NL@%
  9795. %@AU@% Breakpoints can be  tied to variables.%@AE@%  %@NL@%
  9796. %@NL@%
  9797. Breakpoints are not limited to specific lines of code. CodeView can also
  9798. break execution when a variable reaches a particular value, or just changes
  9799. value. You can also combine these value breakpoints with line breakpoints,
  9800. so that execution stops at a specific line only if a variable has
  9801. simultaneously reached a particular value, or changed value. You must use
  9802. the check boxes in the Set Breakpoint dialog box to select these other types
  9803. of breakpoints.  %@NL@%
  9804. %@NL@%
  9805. To pause execution when an expression reaches a particular value, enter that
  9806. expression in the Expression field of the Set Breakpoint dialog box. For
  9807. example, assume you have declared a tree structure as follows:  %@NL@%
  9808. %@NL@%
  9809. %@AS@%  struct Tagtree
  9810. %@AS@%  {
  9811. %@AS@%      char * s;                /* Pointer to a string */
  9812. %@AS@%      struct TAGtree * left;   /* Pointer to left branch */
  9813. %@AS@%      struct TAGtree * right;  /* Pointer to right branch */
  9814. %@AS@%  };
  9815. %@AS@%  
  9816. %@AS@%  struct TAGtree t;%@AE@%%@NL@%
  9817. %@NL@%
  9818. You can then pause execution when your tree traversal reaches a terminal
  9819. node by entering the expression %@AS@% (t.left == NULL) || (t.right == NULL)%@AE@%.  %@NL@%
  9820. %@NL@%
  9821. To pause execution when a variable changes value, you need to enter only the
  9822. name of the variable in the Expression field. For large variables (such as
  9823. arrays or character strings), you can specify the number of bytes you want
  9824. checked (up to 32K) in the Length field.  %@NL@%
  9825. %@NL@%
  9826. ────────────────────────────────────────────────────────────────────────────%@NL@%
  9827. NOTE
  9828.  
  9829. %@AI@%When a breakpoint is tied to a variable, CodeView must check the variable's
  9830. %@AI@%value after each machine instruction is executed. This slows execution
  9831. %@AI@%greatly. For maximum speed when debugging, either tie conditional
  9832. %@AI@%breakpoints to specific lines, or set conditional breakpoints only after you
  9833. %@AI@%have reached the section of code that needs to be debugged.%@AE@%%@NL@%
  9834. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  9835. %@NL@%
  9836. %@NL@%
  9837. %@4@%%@AB@%Using Breakpoints%@AE@%%@EH@%%@NL@%
  9838. %@NL@%
  9839. Here are several examples that show how breakpoints can help you find the
  9840. cause of a problem.  %@NL@%
  9841. %@NL@%
  9842. One of the most common bugs is a %@AB@%for%@AE@% loop that executes too many or too few
  9843. times. If you set a breakpoint that encloses the loop statements, the
  9844. program pauses after each iteration. With the loop variable or critical
  9845. program variables in the Watch or Local windows, it should be easy to see
  9846. what the loop is doing wrong.  %@NL@%
  9847. %@NL@%
  9848. %@AU@% You can specify how  many times a breakpoint  line is executed.%@AE@%  %@NL@%
  9849. %@NL@%
  9850. You do not have to pause at a breakpoint the first time execution reaches
  9851. it. CodeView lets you specify the number of times you want to ignore the
  9852. breakpoint condition before pausing. Enter the decimal number in the Pass
  9853. Count field of the Set Breakpoint dialog box of the Watch menu.  %@NL@%
  9854. %@NL@%
  9855. For example, suppose your program repeatedly calls a function to create a
  9856. binary tree. You suspect that something goes wrong with the process about
  9857. halfway through. You could mark the line that calls the function as the
  9858. breakpoint, then specify how many times this line is to execute before
  9859. execution pauses. Running the program creates a representative (but
  9860. unfinished) tree structure that can be examined from the Watch window. You
  9861. can then continue your analysis using single-stepping.  %@NL@%
  9862. %@NL@%
  9863. Another programming error is erroneously assigning a value to a variable.
  9864. Enter the variable in the Expression field of the Set Breakpoint dialog box.
  9865. Execution breaks whenever this variable changes value.  %@NL@%
  9866. %@NL@%
  9867. %@AU@% You can assign new  values to variables while  execution is paused.%@AE@%  %@NL@%
  9868. %@NL@%
  9869. Breakpoints are a convenient way to pause the program so you can assign new
  9870. values to variables. For example, if a limit value is set by a variable, you
  9871. can change the value to see whether program execution is affected.
  9872. Similarly, you can pass a variety of values to a %@AB@%switch%@AE@% statement to see if
  9873. they are correctly processed.  %@NL@%
  9874. %@NL@%
  9875. This ability to alter variables is an especially convenient way to test new
  9876. functions without having to write a stand-alone test program.  %@NL@%
  9877. %@NL@%
  9878. %@NL@%
  9879. %@3@%%@CR:C6A00090017 @%%@AB@%9.4.2  Single-Stepping%@AE@%%@EH@%%@NL@%
  9880. %@NL@%
  9881. In single-stepping, CodeView pauses after each line of code is executed. (If
  9882. a line contains more than one executable statement, CodeView executes all
  9883. the statements on the line before pausing.) The next line to be executed is
  9884. highlighted in reverse video.  %@NL@%
  9885. %@NL@%
  9886. %@AU@% There are two ways  to single-step.%@AE@%  %@NL@%
  9887. %@NL@%
  9888. You can single-step through a program with the Step and Trace functions.
  9889. Step (executed by pressing F10) steps over function calls. All the code in
  9890. the function is executed but, to you, the function appears to execute as a
  9891. single step. Trace (executed by pressing F8) traces through every step of
  9892. all functions for which CodeView has symbolic information. Each line of the
  9893. function is executed as a separate step. (CodeView has no symbolic
  9894. information about run-time functions; therefore, they are executed as a
  9895. single step.)  %@NL@%
  9896. %@NL@%
  9897. You can alternate between Trace and Step as you like. The method you use
  9898. depends only on whether you want to see what happens within a particular
  9899. function.  %@NL@%
  9900. %@NL@%
  9901. You can Trace through the program continuously (without having to press F8),
  9902. using the Animate command of the Run menu. The speed of execution is
  9903. controlled by the Trace Speed command from the Options menu. You can halt
  9904. animated execution at any time by pressing any key.  %@NL@%
  9905. %@NL@%
  9906. %@NL@%
  9907. %@2@%%@CR:C6A00090018 @%%@AB@%9.5  Replaying a Debug Session%@AE@%%@EH@%%@NL@%
  9908. %@NL@%
  9909. CodeView can automatically create a "tape" (a disk file) with all the
  9910. debugging instructions and input data you entered when testing a program.
  9911. The tape is then "replayed" to repeat the debugging process. This dynamic
  9912. replay feature is unique to the CodeView debugger and is activated by
  9913. selecting the History On command from the Run menu. Selecting History On a
  9914. second time terminates  recording.  %@NL@%
  9915. %@NL@%
  9916. You can use the recording as a bookmark. You can quit after a long debugging
  9917. session, then pick up the session later in the same place.  %@NL@%
  9918. %@NL@%
  9919. %@AU@% Dynamic replay makes it  easy to correct a mistake.%@AE@%  %@NL@%
  9920. %@NL@%
  9921. The principal use of dynamic replay is to allow you to back up when you make
  9922. an error or overshoot the section of code with the bug. This feature is
  9923. important because not all bugs are located when executing the program in a
  9924. linear fashion.  %@NL@%
  9925. %@NL@%
  9926. For example, you may have to manually execute a function many times before
  9927. its bug appears. If you then enter a command that alters the machine's or
  9928. program's status and thereby lose the information you need to find the cause
  9929. of the bug, you would have had to restart the program and manually repeat
  9930. every debugging step to return to that point. Even worse, if you don't
  9931. remember the exact sequence of events that exposed the bug, it could take
  9932. hours to find your way back.  %@NL@%
  9933. %@NL@%
  9934. Dynamic replay eliminates this problem. Selecting the Undo command from the
  9935. Run menu automatically restarts the program and rapidly executes every debug
  9936. command up to (but not including) the last one you entered. You can repeat
  9937. this process as many times as you like until you return to the desired point
  9938. in execution.  %@NL@%
  9939. %@NL@%
  9940. To add additional steps to an existing tape, select History On, then select
  9941. Replay. When replay has completed, perform whatever new debugging steps you
  9942. want, then select History On a second time to terminate recording. The new
  9943. tape contains both the original and the added commands.  %@NL@%
  9944. %@NL@%
  9945. ────────────────────────────────────────────────────────────────────────────%@NL@%
  9946. NOTE
  9947.  
  9948. %@AI@%CodeView records only those mouse commands that apply to CodeView. Mouse
  9949. %@AI@%commands recognized by the application being debugged are not recorded.%@AE@%%@NL@%
  9950. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  9951. %@NL@%
  9952. %@NL@%
  9953. %@4@%%@AB@%Replay Limitations under OS/2%@AE@%%@EH@%%@NL@%
  9954. %@NL@%
  9955. There are some limitations to dynamic replay when debugging under OS/2:  %@NL@%
  9956. %@NL@%
  9957. %@NL@%
  9958.   ■   The program must not respond to asynchronous events.%@NL@%
  9959. %@NL@%
  9960.   ■   Breakpoints must be specified at specific source lines or for specific
  9961.       symbols (rather than by absolute addresses), or replay may fail.%@NL@%
  9962. %@NL@%
  9963.   ■   Single-thread programs behave normally during replay. However, one of
  9964.       the threads in a multithread program may cause an asynchronous event,
  9965.       violating the first restriction. Multithread programs are, therefore,
  9966.       more likely to fail during replay.%@NL@%
  9967. %@NL@%
  9968.   ■   Multiprocess replay will fail. Each new process invokes a new CodeView
  9969.       session. The existence of multiple sessions makes it impractical to
  9970.       record the sequence of events if you execute commands in a session
  9971.       other than the original.%@NL@%
  9972. %@NL@%
  9973.   ■   Replay under Presentation Manager is not currently supported because
  9974.       it violates the first restriction.%@NL@%
  9975. %@NL@%
  9976. %@NL@%
  9977. %@NL@%
  9978. %@2@%%@CR:C6A00090019 @%%@AB@%9.6  Advanced CodeView Techniques%@AE@%%@EH@%%@NL@%
  9979. %@NL@%
  9980. Once you are comfortable displaying and changing variables, stepping through
  9981. the program, and using dynamic replay, you might want to experiment with the
  9982. advanced techniques explained below.  %@NL@%
  9983. %@NL@%
  9984. %@NL@%
  9985. %@4@%%@AB@%Setting Command-Line Arguments%@AE@%%@EH@%%@NL@%
  9986. %@NL@%
  9987. If your program retrieves command-line arguments, you can specify them with
  9988. the Set Runtime Arguments command from the Run menu. Enter the arguments in
  9989. the Command Line field before you begin execution. (Arguments entered after
  9990. execution begins cause an automatic restart.)  %@NL@%
  9991. %@NL@%
  9992. %@NL@%
  9993. %@4@%%@AB@%Multiple Source Windows%@AE@%%@EH@%%@NL@%
  9994. %@NL@%
  9995. You can open two Source windows at the same time. The windows can display
  9996. two different sections of the same program, or one can show the high-level
  9997. listing and the other the assembly-language listing. In the latter case, the
  9998. contents of the windows track, with the next assembly-language instruction
  9999. to be executed matching the next line of source code.  %@NL@%
  10000. %@NL@%
  10001. You can move freely between these windows, executing a single line of source
  10002. code or a single assembly instruction at a time. The assembly-language
  10003. window must be opened in CS:IP mode.  %@NL@%
  10004. %@NL@%
  10005. %@NL@%
  10006. %@4@%%@AB@%Calling Functions%@AE@%%@EH@%%@NL@%
  10007. %@NL@%
  10008. Any C function in your program (whether user-written or from the library)
  10009. can be called from the Command window or the Watch window, using the
  10010. following format:  %@NL@%
  10011. %@NL@%
  10012. %@AS@%  ?funcname (varlist)%@AE@%%@NL@%
  10013. %@NL@%
  10014. The function is evaluated and the returned value is displayed in the Command
  10015. window.  %@NL@%
  10016. %@NL@%
  10017. The function does not have to be called by your program to be available for
  10018. evaluation. For example, all the .OBJ code specified in the linker input
  10019. response file is linked. The functions in this code can then be evaluated
  10020. from the Command window.  %@NL@%
  10021. %@NL@%
  10022. This feature allows you to run functions from within CodeView that you would
  10023. not normally include in the final version of your program. For example, you
  10024. could include the OS/2 API functions that control semaphores, then execute
  10025. them from the Command window to manipulate the run-time environment at any
  10026. point in the debugging process.  %@NL@%
  10027. %@NL@%
  10028. %@NL@%
  10029. %@4@%%@AB@%Checking for Undefined Pointers%@AE@%%@EH@%%@NL@%
  10030. %@NL@%
  10031. Until a pointer has been explicitly assigned a value, its value is
  10032. undefined. That is, its value may be completely random, or it may be some
  10033. consistent value that does not point to a useful data address (such as -1).
  10034. %@NL@%
  10035. %@NL@%
  10036. Accessing data through an uninitialized pointer will cause unpredictable
  10037. program behavior and, under OS/2, will usually result in a protection
  10038. violation. Because many C programs use pointers heavily, tracking down
  10039. exactly which pointer variable was left uninitialized is tedious.  %@NL@%
  10040. %@NL@%
  10041. CodeView can help locate the problem quickly. If you use an uninitialized
  10042. pointer (or "null pointer" under OS/2) the operating system will generate a
  10043. protection violation. By examining the Calls menu, you can determine the
  10044. last line of your code that was executed before the protection violation
  10045. occurred.  %@NL@%
  10046. %@NL@%
  10047. Under DOS, you can take advantage of the fact that global or static
  10048. variables are initialized to 0 to track down uninitialized pointers. Set a
  10049. conditional breakpoint that stops when location 0 changes, then start
  10050. execution. Execution will pause when your program makes an assignment to
  10051. that location.  %@NL@%
  10052. %@NL@%
  10053. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10054. NOTE
  10055.  
  10056. %@AI@%For near pointers, location 0 is DS:0000; for far pointers, location 0 is
  10057. %@AI@%0000:0000.%@AE@%%@NL@%
  10058. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  10059. %@NL@%
  10060. %@NL@%
  10061. %@4@%%@AB@%Using Breakpoints Efficiently%@AE@%%@EH@%%@NL@%
  10062. %@NL@%
  10063. Breakpoints slow execution when debugging. You can increase CodeView's speed
  10064. by using the /R command-line switch if you have an 80386-based computer.
  10065. This switch enables the 386's four debug registers, which support breakpoint
  10066. checking in hardware rather than in software.  %@NL@%
  10067. %@NL@%
  10068. %@NL@%
  10069. %@4@%%@AB@%Printing Selected Items%@AE@%%@EH@%%@NL@%
  10070. %@NL@%
  10071. You can print all or part of the contents of any window with the Print
  10072. command from the File menu. The check box lets you print the complete
  10073. contents of the window, only the material that is currently viewable in the
  10074. window, or selected text from the window. Text is selected by dragging the
  10075. mouse across it, or by holding down the SHIFT key and pressing the direction
  10076. keys (LEFT, RIGHT, UP, DOWN).  %@NL@%
  10077. %@NL@%
  10078. By default, print output is to the file CODEVIEW.LST in the current
  10079. directory. You can choose whether the new material will be appended to an
  10080. existing file or overwrite it, using the Append/Overwrite check box. If you
  10081. would like print output to go to a different file, type its name in the To
  10082. File Name field. If you want the output to go to a printer, enter the
  10083. appropriate device name, such as LPT1 or COM2.%@CR:C6A00090020 @%%@CR:C6A00090021 @%  %@NL@%
  10084. %@NL@%
  10085. %@NL@%
  10086. %@4@%%@AB@%Handling Register Variables%@AE@%%@EH@%%@NL@%
  10087. %@NL@%
  10088. A register variable is stored in one of the microprocessor's registers,
  10089. rather than in RAM. This speeds access to the variable.  %@NL@%
  10090. %@NL@%
  10091. There are two ways for a conventional variable to become a register
  10092. variable. One way is declaring the variable as a register variable; if a
  10093. register is free, the compiler will store the variable there. The other way
  10094. occurs during optimization, when the compiler stores an often-used variable
  10095. (such as a loop variable) in a register to speed up execution.  %@NL@%
  10096. %@NL@%
  10097. Register variables can cause problems during debugging. As with local
  10098. variables, they are only visible within the function where they are defined.
  10099. In addition, a register variable may not always be displayed with its
  10100. current value.  %@NL@%
  10101. %@NL@%
  10102. In general, it is a good idea to turn off all optimization and to avoid
  10103. declaring register variables until the program has been fully debugged. Any
  10104. side effects produced by optimization or register variables can then be
  10105. easily isolated.  %@NL@%
  10106. %@NL@%
  10107. %@NL@%
  10108. %@4@%%@AB@%Redirecting CodeView Input and Output%@AE@%%@EH@%%@NL@%
  10109. %@NL@%
  10110. The Command window accepts DOS-like commands that redirect input and output.
  10111. These commands can also be included on the command line that invokes
  10112. CodeView. Whatever follows the /C option in the command line is treated as
  10113. CodeView commands that are immediately executed at start-up.  %@NL@%
  10114. %@NL@%
  10115. %@AS@%  CV/c "infile; t >outfile" myprog%@AE@%%@NL@%
  10116. %@NL@%
  10117. Input is redirected to %@AS@% infile%@AE@%, which can contain start-up commands for
  10118. CodeView. When CodeView exhausts all commands in the input file, focus
  10119. automatically shifts to the command window. Output is sent to %@AS@% outfile %@AE@% and
  10120. echoed to the Command window. The %@AS@% t %@AE@% must precede the %@AS@% > %@AE@% command for
  10121. output to be sent to the Command window.  %@NL@%
  10122. %@NL@%
  10123. Redirection is a useful way to automate CodeView start-up. It also lets you
  10124. keep a viewable record of command-line input and output, a feature not
  10125. available with dynamic replay. (No record is kept of mouse operations.) Some
  10126. applications (particularly interactive ones) may need modification to allow
  10127. for redirection of input to the application itself.  %@NL@%
  10128. %@NL@%
  10129. %@NL@%
  10130. %@4@%%@AB@%Using CodeView with Additional Memory%@AE@%%@EH@%%@NL@%
  10131. %@NL@%
  10132. If your computer uses expanded or extended memory, you can increase
  10133. CodeView's functionality by selecting the /X or /E option. CodeView moves as
  10134. much as it can of itself, the debugging table, and the program to higher
  10135. memory (above the first megabyte).  %@NL@%
  10136. %@NL@%
  10137. The /X option uses extended memory and gives the greatest speed increase.
  10138. This option requires the HIMEM.SYS driver, which is included on your
  10139. distribution disks. Add %@AS@% DEVICE = HIMEM.SYS %@AE@% to your CONFIG.SYS file to load
  10140. HIMEM.SYS at boot time.%@CR:C6A00090022 @%%@CR:C6A00090023 @%%@CR:C6A00090024 @%  %@NL@%
  10141. %@NL@%
  10142. The /E option uses expanded memory. The speed increase is not as great as
  10143. that supplied by the /X option. The expanded memory manager (EMM) must be
  10144. LIM 4.0, and no single module's debug information can exceed 48K. If the
  10145. symbol table exceeds this limit, try reducing file-name information by not
  10146. specifying paths at compile time and using /Zi only with those sections of
  10147. the program that need debugging (use /Zd otherwise).  %@NL@%
  10148. %@NL@%
  10149. If you do not specify either /X or /E (or the /D disk-overlay option),
  10150. CodeView automatically searches for the HIMEM.SYS driver and extended memory
  10151. so it can implement the /X option. If it fails, CodeView searches for
  10152. expanded memory to implement the /E option. If that search fails, CodeView
  10153. uses a default disk overlay of 64K. (See the description of the /D option
  10154. below.)  %@NL@%
  10155. %@NL@%
  10156. %@NL@%
  10157. %@2@%%@CR:C6A00090025 @%%@AB@%9.7  Controlling CodeView with Command-Line Options%@AE@%%@EH@%%@NL@%
  10158. %@NL@%
  10159. The following options can be added to the command line that invokes
  10160. CodeView:  %@NL@%
  10161. %@NL@%
  10162. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  10163. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10164. /2                                Two-monitor debugging. The display 
  10165.                                   adapters must be configured for 
  10166.                                   different addresses. One display shows 
  10167.                                   the output of the application; the other
  10168.                                   shows CodeView.
  10169.  
  10170. /25                               Display in 25-line mode.
  10171.  
  10172. /43                               Display in 43-line mode (EGA or VGA 
  10173.                                   only).
  10174.  
  10175. /50                               Display in 50-line mode (VGA only).
  10176.  
  10177. /B                                Display in black and white. This assures
  10178.                                   that the display is readable when a 
  10179.                                   color display is not used.
  10180.  
  10181. /C%@AI@%commands%@AE@%                        All items following this switch are 
  10182.                                   treated as CodeView commands to be 
  10183.                                   executed immediately on start-up. 
  10184.                                   Commands must be separated with a 
  10185.                                   semicolon (%@AB@%;%@AE@%).
  10186.  
  10187. /D«%@AI@%ddd%@AE@%»                           Use disk overlays, where %@AI@%ddd%@AE@% is the 
  10188.                                   decimal size of the overlay buffer, in 
  10189.                                   kilobytes. The acceptable range is 16K 
  10190.                                   to 128K. The default size is 64K. DOS 
  10191.                                   only.
  10192.  
  10193. /E                                Use expanded memory for symbolic 
  10194.                                   information. DOS only.
  10195.  
  10196. /F                                Flip screen video pages. When your 
  10197.                                   application does not use graphics, eight
  10198.                                   video screen pages are available. 
  10199.                                   Switching from CodeView to the output 
  10200.                                   screen is accomplished more quickly than
  10201.                                   swapping (/S) by directly selecting the 
  10202.                                   appropriate video page. Cannot be used 
  10203.                                   with /S. DOS only.
  10204.  
  10205. /I%@AI@%number%@AE@%                          Turns nonmaskable interrupts and 
  10206.                                   8259-interrupt trapping on (/I1) or off 
  10207.                                   (/I2).
  10208.  
  10209. /K                                Disables installation of keyboard 
  10210.                                   monitors for the program being debugged.
  10211.  
  10212. /L%@AI@%dlls%@AE@%                            Load DLLs specified. DLLs must be 
  10213.                                   separated by a semicolon (%@AB@%;%@AE@%). OS/2 only.
  10214.  
  10215. /M                                Disable the mouse.
  10216.  
  10217. /N%@AI@%number%@AE@%                          /N0 tells CodeView to trap; /N1 tells it
  10218.                                   not to.
  10219.  
  10220. /O                                Debug child processes ("offspring"). 
  10221.                                   OS/2 only.
  10222.  
  10223. /R                                Use 386 hardware debug registers. DOS 
  10224.                                   only.
  10225.  
  10226. /S                                Swap screen in buffers. When your 
  10227.                                   program uses graphics, all eight screen 
  10228.                                   buffers must be used. Switching from 
  10229.                                   CodeView to the output screen is
  10230.                                   accomplished by saving the previous 
  10231.                                   screen in a buffer. Cannot be used with 
  10232.                                   /F. DOS only.
  10233.  
  10234. /X                                Use extended memory for symbolic 
  10235.                                   information. DOS only.
  10236.  
  10237. %@NL@%
  10238. %@2@%%@CR:C6A00090026 @%%@AB@%9.8  Customizing CodeView with the TOOLS.INI FILE%@AE@%%@EH@%%@NL@%
  10239. %@NL@%
  10240. The TOOLS.INI file customizes the behavior and user interface of several
  10241. Microsoft products. The TOOLS.INI file is a plain ASCII text file. You
  10242. should place it in a directory pointed to the INIT environment variable. (If
  10243. you do not use the INIT environment variable, CodeView looks for TOOLS.INI
  10244. only in its source directory.)  %@NL@%
  10245. %@NL@%
  10246. The CodeView section of TOOLS.INI is preceded by the following line:  %@NL@%
  10247. %@NL@%
  10248. %@AS@%  [cv]%@AE@%%@NL@%
  10249. %@NL@%
  10250. If you are running the protected-mode version of CodeView, use %@AS@% [cvp] %@AE@%
  10251. instead. If you run both versions, include both: %@AS@% [cv cvp]%@AE@%.  %@NL@%
  10252. %@NL@%
  10253. Most of the TOOLS.INI customizations control screen colors, but you can also
  10254. specify such things as start-up commands or the name of the file that
  10255. receives CodeView output. On-line help contains full information about all
  10256. TOOLS.INI switches for CodeView.  %@NL@%
  10257. %@NL@%
  10258. %@NL@%
  10259. %@NL@%
  10260. %@NL@%
  10261. %@NL@%
  10262. %@NL@%
  10263. %@CR:C6A-Part 03 @%%@1@%%@AB@%PART III  Special Environments%@AE@%%@EH@%%@NL@%
  10264. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10265. %@NL@%
  10266. The Microsoft C Professional Development System provides a platform from
  10267. which you can build graphics applications and interface with programs
  10268. written in other languages.  %@NL@%
  10269. %@NL@%
  10270. Chapter 10 discusses using the real-world graphics functions to set video
  10271. modes, draw basic shapes, and use graphic fonts. Chapter 11 describes
  10272. "presentation graphics," sophisticated charts and graphics that show data
  10273. relationships. Chapter 12 explains how to write C programs so that they
  10274. interface with assembly language routines or routines written in other
  10275. languages. Chapter 13 describes portability of Microsoft C to other
  10276. environments.  %@NL@%
  10277. %@NL@%
  10278. %@NL@%
  10279. %@NL@%
  10280. %@NL@%
  10281. %@NL@%
  10282. %@NL@%
  10283. %@CR:C6A00100001 @%%@1@%%@AB@%Chapter 10  Communicating with Graphics%@AE@%%@EH@%%@NL@%
  10284. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10285. %@NL@%
  10286. A map, a chart, an illustration, a graph, or some other visual aid often can
  10287. communicate more information more quickly and more vividly than would
  10288. several screens of text.  %@NL@%
  10289. %@NL@%
  10290. The extensive Microsoft C graphics library allows you to communicate your
  10291. ideas graphically. The functions range from the simple to the complex; from
  10292. functions that turn on a pixel to functions that draw graphs and charts
  10293. complete with labels and legends.  %@NL@%
  10294. %@NL@%
  10295. This chapter describes low-level graphics functions that draw basic shapes
  10296. such as lines, circles, and rectangles. It introduces video modes, color
  10297. palettes, coordinate systems, and synopses of the graphics and font
  10298. functions. For complete function prototypes and example programs, use
  10299. on-line help.  %@NL@%
  10300. %@NL@%
  10301. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10302. NOTE
  10303.  
  10304. %@AI@%The ANSI C standard does not define any standard graphics functions. The
  10305. %@AI@%functions described in this section are unique to Microsoft C and are not
  10306. %@AI@%portable to other implementations of C.%@AE@%%@NL@%
  10307. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  10308. %@NL@%
  10309. %@NL@%
  10310. %@2@%%@CR:C6A00100002 @%%@AB@%10.1  Video Modes%@AE@%%@EH@%%@NL@%
  10311. %@NL@%
  10312. Graphics adapters are boards or cards inside the computer that are
  10313. responsible for displaying text and graphics on the screen. Commonly used
  10314. adapters include:  %@NL@%
  10315. %@NL@%
  10316. %@NL@%
  10317.   ■   CGA (Color Graphics Adapter)%@NL@%
  10318. %@NL@%
  10319.   ■   EGA (Enhanced Graphics Adapter)%@NL@%
  10320. %@NL@%
  10321.   ■   HGC (Hercules Graphics Card)%@NL@%
  10322. %@NL@%
  10323.   ■   MCGA (Multicolor Graphics Array)%@NL@%
  10324. %@NL@%
  10325.   ■   MDPA (Monochrome Display Printer Adapter)%@NL@%
  10326. %@NL@%
  10327.   ■   VGA (Video Graphics Array)%@NL@%
  10328. %@NL@%
  10329. %@NL@%
  10330. In addition, there are Olivetti versions of the CGA, EGA, and VGA (called
  10331. OCGA, OEGA, and OVGA in this chapter).  %@NL@%
  10332. %@NL@%
  10333. %@AU@% The video modes available at run time depend on your graphics adapter and
  10334. %@AU@%monitor.%@AE@%  %@NL@%
  10335. %@NL@%
  10336. Adapters can enter one or more "video modes." The video mode controls the
  10337. resolution and number of colors on the video display. Microsoft C supports
  10338. 17 video modes, which fall into two broad categories:  %@NL@%
  10339. %@NL@%
  10340. %@NL@%
  10341.   ■   "Text modes," where characters are displayed%@NL@%
  10342. %@NL@%
  10343.   ■   "Graphics modes," where individual pixels can be turned on and off%@NL@%
  10344. %@NL@%
  10345. %@NL@%
  10346. The graphics adapter and the type of monitor in use determine which of the
  10347. 17 video modes are available at run time. See Section 10.1.2 for a list of
  10348. video modes.  %@NL@%
  10349. %@NL@%
  10350. %@NL@%
  10351. %@3@%%@CR:C6A00100003 @%%@AB@%10.1.1  Sample Low-Level Graphics Program%@AE@%%@EH@%%@NL@%
  10352. %@NL@%
  10353. The program ERESBOX.C below shows, in a few lines, the steps you follow to
  10354. enter and exit a graphics mode. It sets the video mode %@AB@%_ERESCOLOR%@AE@%, draws a
  10355. box, waits for a keypress, and returns to default mode, which is the video
  10356. mode in effect when the program began running.%@CR:C6A00100004 @%%@CR:C6A00100005 @%%@CR:C6A00100006 @%  %@NL@%
  10357. %@NL@%
  10358. %@AS@%  /* ERESBOX.C -- Enters _ERESCOLOR mode and draws a box */
  10359. %@AS@%  
  10360. %@AS@%  #include <graph.h> /* graphics functions */
  10361. %@AS@%  #include <stdio.h> /* puts */
  10362. %@AS@%  #include <conio.h> /* getch */
  10363. %@AS@%  
  10364. %@AS@%  main()
  10365. %@AS@%  {
  10366. %@AS@%     if( _setvideomode( _ERESCOLOR ) ) /* EGA 640x350 mode */
  10367. %@AS@%     {
  10368. %@AS@%        _rectangle( _GBORDER, 10, 10, 110, 110 ); /* draw */
  10369. %@AS@%        getch(); /* wait for a keypress */
  10370. %@AS@%        _setvideomode( _DEFAULTMODE ); /* return to default */
  10371. %@AS@%     } else puts( "Can't enter _ERESCOLOR graphics mode." )
  10372. %@AS@%  }%@AE@%%@NL@%
  10373. %@NL@%
  10374. The program above illustrates the steps you follow to display graphics:  %@NL@%
  10375. %@NL@%
  10376. %@NL@%
  10377.   ■   Include the header file GRAPH.H. It contains function prototypes,
  10378.       macros, useful structures, and symbolic constants such as %@AB@%_ERESCOLOR%@AE@%,
  10379.       %@AB@%_GBORDER%@AE@%, and %@AB@%_DEFAULTMODE%@AE@%.
  10380. %@NL@%
  10381. %@AS@%      #include <graph.h>%@AE@%%@NL@%
  10382. %@NL@%
  10383. %@NL@%
  10384.   ■   Call the %@AB@%_setvideomode%@AE@% function, which sets the desired video mode.
  10385.       The function returns 0 if the hardware does not support the requested
  10386.       mode. (See Section 10.1.2, "Setting a Video Mode.")
  10387. %@NL@%
  10388. %@AS@%      if( _setvideomode( _ERESCOLOR ) )%@AE@%%@NL@%
  10389. %@NL@%
  10390. %@NL@%
  10391.   ■   Draw the graphics on the screen. The example program calls the
  10392.       %@AB@%_rectangle%@AE@% function. (See Section 10.4.3, "Drawing Points, Lines, and
  10393.       Shapes.")
  10394. %@NL@%
  10395. %@AS@%      _rectangle( _GBORDER, 10, 10, 110, 110 )%@AE@%%@NL@%
  10396. %@NL@%
  10397. %@NL@%
  10398.   ■   Exit the graphics mode and return to whatever video mode was in effect
  10399.       before the program began. Call %@AB@%_setvideomode%@AE@%, passing the constant
  10400.       %@AB@%_DEFAULTMODE%@AE@%. In some cases, you might want to skip this step, exiting
  10401.       the program with the graphics screen still in place.
  10402. %@NL@%
  10403. %@AS@%      _setvideomode( _DEFAULTMODE );%@AE@%%@NL@%
  10404. %@NL@%
  10405. %@NL@%
  10406. %@NL@%
  10407. In addition, you must link with the GRAPHICS.LIB library, which contains the
  10408. function code. If you use window-coordinate functions (which require
  10409. floating-point calculations) and if you have not created a standard combined
  10410. library containing a floating-point component, you must explicitly link with
  10411. a floating-point math library.  %@NL@%
  10412. %@NL@%
  10413. %@NL@%
  10414. %@3@%%@CR:C6A00100007 @%%@AB@%10.1.2  Setting a Video Mode%@AE@%%@EH@%%@NL@%
  10415. %@NL@%
  10416. The %@AB@%_setvideomode%@AE@% function turns on one of the 17 available video modes.
  10417. Pass it a single integer that tells it which mode to display. The constants
  10418. in Table 10.1 are defined in the GRAPH.H file. The dimensions are listed in
  10419. pixels for video graphics mode and in columns for video text mode.  %@NL@%
  10420. %@NL@%
  10421. %@AB@%Table 10.1  %@AB@%Constants that Represent Video Modes%@AE@%%@AE@%
  10422.  
  10423. %@TH:  45  2006 02 17 40 19 @%
  10424. Constant (Name)  Description                             Mode/Hardware
  10425. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10426. %@AB@%_DEFAULTMODE%@AE@%     Restores the original mode              All/All
  10427.  
  10428. %@AB@%_ERESCOLOR%@AE@%       640  x  350, 4 or 16 color              Graphics/EGA
  10429.  
  10430. %@AB@%_ERESNOCOLOR%@AE@%     640  x  350, BW                         Graphics/EGA
  10431.  
  10432. %@AB@%_HRES16COLOR%@AE@%     640  x  200, 16 color                   Graphics/EGA
  10433.  
  10434. %@AB@%_HERCMONO%@AE@%*%@AB@% %@AE@%      720  x 348, BW                          Graphics/HGC
  10435.  
  10436. %@AB@%_HRESBW%@AE@%          640  x  200, BW                         Graphics/CGA
  10437.  
  10438. %@AB@%_MAXCOLORMODE%@AE@%    Graphics mode with the most colors      Graphics/All┼
  10439.  
  10440. %@AB@%_MAXRESMODE%@AE@%      Graphics mode with the highest          Graphics/All┼
  10441.                  resolution                              
  10442.  
  10443. %@AB@%_MRES4COLOR%@AE@%      320  x  200, 4 color                    Graphics/All
  10444.  
  10445. %@AB@%_MRES16COLOR%@AE@%     320  x  200, 16 color                   Graphics/EGA
  10446.  
  10447. %@AB@%_MRES256COLOR%@AE@%    320  x  200, 256 color                  Graphics/VGA
  10448.  
  10449. %@AB@%_MRESNOCOLOR%@AE@%     320  x  200, 4 gray                     Graphics/CGA
  10450.  
  10451. %@AB@%_ORESCOLOR%@AE@%       640  x  400, 1 of 16 colors             Graphics/Olivetti
  10452.  
  10453. %@AB@%_TEXTBW40%@AE@%        40 column text, 16 gray                 Text/CGA
  10454.  
  10455. %@AB@%_TEXTBW80%@AE@%        80 column text, 16 gray                 Text/CGA
  10456.  
  10457. %@AB@%_TEXTC40%@AE@%         40 column text, 16/8 color              Text/CGA
  10458.  
  10459. %@AB@%_TEXTC80%@AE@%         80 column text, 16/8 color              Text/CGA
  10460.  
  10461. %@AB@%_TEXTMONO%@AE@%        80 column text, BW                      Text/MDPA
  10462.  
  10463. %@AB@%_VRES2COLOR%@AE@%      640  x  480, BW                         Graphics/VGA
  10464.  
  10465. %@AB@%_VRES16COLOR%@AE@%     640  x  480, 16 color                   Graphics/VGA
  10466.  
  10467. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10468.  
  10469. %@TE:  45  2006 02 17 40 19 @%
  10470.  
  10471. *%@AB@% %@AE@%Before attempting to enter%@AB@% _HERCMONO%@AE@% mode, you must install the
  10472. terminate-and-stay-resident program MSHERC.COM, which comes in the Microsoft
  10473. C package. If you have both a Hercules adapter and an additional graphics
  10474. adapter in the same computer, use the /H option  to put the Hercules into
  10475. %@AB@%HALF %@AE@%mode to avoid unpredictable and undesirable results.
  10476. ┼ %@AB@%_MAXRESMODE%@AE@% and%@AB@% _MAXCOLORMODE %@AE@%support all adapters except the MDPA. See
  10477. Section  %@NL@%
  10478. %@NL@%
  10479. %@NL@%
  10480. If the hardware does not support the selected mode, %@AB@%_setvideomode%@AE@% returns 0.
  10481. %@NL@%
  10482. %@NL@%
  10483. Some graphics adapters are able to enter additional video modes:  %@NL@%
  10484. %@NL@%
  10485. %@NL@%
  10486.   ■   EGA adapters can display all CGA modes.  %@NL@%
  10487. %@NL@%
  10488.   ■   HGC adapters can enter %@AB@%_TEXTMONO%@AE@% mode.  %@NL@%
  10489. %@NL@%
  10490.   ■   MCGA adapters can display all CGA modes, plus %@AB@%_VRES2COLOR%@AE@% and
  10491.       %@AB@%_MRES256COLOR%@AE@%.%@NL@%
  10492. %@NL@%
  10493.   ■   VGA adapters can display all EGA and CGA modes.  %@NL@%
  10494. %@NL@%
  10495. %@NL@%
  10496. %@NL@%
  10497. %@3@%%@CR:C6A00100008 @%%@AB@%10.1.3  Reading the videoconfig Structure%@AE@%%@EH@%%@NL@%
  10498. %@NL@%
  10499. At any time, you can inquire about the current video configuration by
  10500. passing the %@AB@%_getvideoconfig%@AE@% function a structure of type %@AB@%videoconfig%@AE@%. The
  10501. structure contains 11 members, all of which are short integers. They are
  10502. listed in Table 10.2.  %@NL@%
  10503. %@NL@%
  10504. %@AB@%Table 10.2  %@AB@%Members of a videoconfig Structure%@AE@%%@AE@%
  10505.  
  10506. %@TH:  14   967 02 23 53 @%
  10507. Member                 Description
  10508. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10509. %@AB@%adapter%@AE@%*               Active display adapter
  10510. %@AB@%bitsperpixel%@AE@%           Number of bits per pixel
  10511. %@AB@%memory%@AE@%                 Adapter video memory in kilobytes
  10512. %@AB@%mode%@AE@%*                  Current video mode
  10513. %@AB@%monitor%@AE@%*               Active display monitor
  10514. %@AB@%numcolors%@AE@%              Number of color indexes
  10515. %@AB@%numtextcols%@AE@%            Number of text columns available
  10516. %@AB@%numtextrows%@AE@%            Number of text rows available
  10517. %@AB@%numvideopages%@AE@%          Number of video pages available
  10518. %@AB@%numxpixels%@AE@%             Number of pixels on the %@AI@%x%@AE@% axis
  10519. %@AB@%numypixels%@AE@%             Number of pixels on the %@AI@%y%@AE@% axis
  10520. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10521. %@TE:  14   967 02 23 53 @%
  10522.  
  10523. * Possible values for the mode, adapter, and monitor items are listed in the
  10524. GRAPH.H file.%@NL@%
  10525. %@NL@%
  10526. %@NL@%
  10527. The %@AB@%_getvideoconfig%@AE@% function initializes these values. Most of the values
  10528. are self-explanatory. For example, if %@AB@%numxpixels%@AE@% holds 640, the current
  10529. video mode contains 640 horizontal pixels, numbered 0 - 639.  %@NL@%
  10530. %@NL@%
  10531. The READVC.C example program below illustrates how to initialize and examine
  10532. a %@AB@%videoconfig%@AE@% structure:  %@NL@%
  10533. %@NL@%
  10534. %@AS@%  /* READVC.C -- Reads the videoconfig structure */
  10535. %@AS@%  
  10536. %@AS@%  #include <graph.h>
  10537. %@AS@%  #include <stdio.h>
  10538. %@AS@%  
  10539. %@AS@%  main()
  10540. %@AS@%  {
  10541. %@AS@%     struct videoconfig vc;
  10542. %@AS@%  
  10543. %@AS@%     _getvideoconfig( &vc );
  10544. %@AS@%     printf( "Text Rows = %i.\n", vc.numtextrows );
  10545. %@AS@%  }%@AE@%%@NL@%
  10546. %@NL@%
  10547. First, the program declares a structure %@AS@% vc %@AE@% of type %@AB@%videoconfig%@AE@%. Next, it
  10548. calls %@AB@%_getvideoconfig%@AE@% to initialize the structure. Finally, it prints a
  10549. member of the structure.  %@NL@%
  10550. %@NL@%
  10551. %@NL@%
  10552. %@3@%%@CR:C6A00100009 @%%@AB@%10.1.4  Maximizing Resolution or Color%@AE@%%@EH@%%@NL@%
  10553. %@NL@%
  10554. Two symbolic constants are new to Microsoft C 6.0:%@AB@% _MAXRESMODE%@AE@% and
  10555. %@AB@%_MAXCOLORMODE%@AE@%. The first selects the highest possible resolution for the
  10556. graphics adapter and monitor currently in use. The second selects the
  10557. graphics mode with the greatest number of colors. The constants work with
  10558. all graphics adapters except the MDPA. (See Table 10.3.)  %@NL@%
  10559. %@NL@%
  10560. %@AB@%Table 10.3  %@AB@%Constants for Maximum Resolution and Color%@AE@%%@AE@%
  10561.  
  10562. %@TH:  14   988 02 17 15 44 @%
  10563. Adapter/Monitor  _MAXRESMODE    _MAXCOLORMODE
  10564. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10565. CGA              %@AB@%_HRESBW%@AE@%        %@AB@%_MRES4COLOR%@AE@%
  10566. EGA color        %@AB@%_HRES16COLOR%@AE@%   %@AB@%_HRES16COLOR%@AE@%
  10567. EGA ecd 64K      %@AB@%_ERESCOLOR%@AE@%     %@AB@%_HRES16COLOR%@AE@%
  10568. EGA ecd 256K     %@AB@%_ERESCOLOR%@AE@%     %@AB@%_ERESCOLOR%@AE@%
  10569. EGA mono         %@AB@%_ERESNOCOLOR%@AE@%   %@AB@%_ERESNOCOLOR%@AE@%
  10570. HGC              %@AB@%_HERCMONO%@AE@%      %@AB@%_HERCMONO%@AE@%
  10571. MCGA             %@AB@%_VRES2COLOR%@AE@%    %@AB@%_MRES256COLOR%@AE@%
  10572. MDPA             Fails          Fails
  10573. OCGA             %@AB@%_ORESCOLOR%@AE@%     %@AB@%_MRES4COLOR%@AE@%
  10574. OEGA color       %@AB@%_ORESCOLOR%@AE@%     %@AB@%_ERESCOLOR%@AE@%
  10575. VGA/OVGA         %@AB@%_VRES16COLOR%@AE@%   %@AB@%_MRES256COLOR%@AE@%
  10576. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10577. %@TE:  14   988 02 17 15 44 @%
  10578.  
  10579. %@NL@%
  10580. %@3@%%@CR:C6A00100010 @%%@AB@%10.1.5  Selecting Your Own Video Modes%@AE@%%@EH@%%@NL@%
  10581. %@NL@%
  10582. A program that will run only on a single machine with a known graphics
  10583. adapter can enter the appropriate video mode immediately. However, if you
  10584. attempt to run the program on another machine with a different adapter, it
  10585. may not run correctly, if at all.  %@NL@%
  10586. %@NL@%
  10587. If your program might run on a variety of computers and you prefer to select
  10588. your own video modes, initialize a %@AB@%videoconfig %@AE@%structure by calling the
  10589. %@AB@%_getvideoconfig%@AE@% function. Then check the %@AB@%adapter %@AE@%member and use a %@AB@%switch
  10590. %@AB@%%@AE@%statement to enter the selected video mode.  %@NL@%
  10591. %@NL@%
  10592. For example, suppose you know that a program will run on monochrome systems
  10593. equipped with either an EGA adapter or a Hercules adapter. To enter the
  10594. appropriate mode, use code such as this:  %@NL@%
  10595. %@NL@%
  10596. %@AS@%  struct videoconfig vc;
  10597. %@AS@%  
  10598. %@AS@%  _getvideoconfig( &vc );
  10599. %@AS@%  
  10600. %@AS@%  switch( vc.adapter )
  10601. %@AS@%  {
  10602. %@AS@%     case _EGA:
  10603. %@AS@%        _setvideomode( _ERESNOCOLOR );
  10604. %@AS@%        break;
  10605. %@AS@%     case _HGC:
  10606. %@AS@%        _setvideomode( _HERCMONO );
  10607. %@AS@%        break;
  10608. %@AS@%  }%@AE@%%@NL@%
  10609. %@NL@%
  10610. %@NL@%
  10611. %@2@%%@CR:C6A00100011 @%%@AB@%10.2  Mixing Colors and Changing Palettes%@AE@%%@EH@%%@NL@%
  10612. %@NL@%
  10613. Depending on the graphics card installed and the video mode in effect, you
  10614. can display 2, 4, 8, 16, or 256 colors on the screen at the same time. You
  10615. specify a color by selecting a color index (sometimes called a "pixel value"
  10616. or "color attribute"). The color indexes are numbered from 0 to %@AI@%n%@AE@%-1, where %@AI@%n%@AE@%
  10617. is the number of colors in the palette.  %@NL@%
  10618. %@NL@%
  10619. CGA adapters offer four different palettes containing predefined fixed color
  10620. sets.  %@NL@%
  10621. %@NL@%
  10622. %@AU@% All video modes that support color offer a color palette.%@AE@%  %@NL@%
  10623. %@NL@%
  10624. EGA, MCGA, and VGA adapters have palettes that can be redefined to suit your
  10625. needs. You can change the visible color associated with any color index by
  10626. remapping to a color index a color value that describes the true color (the
  10627. amount of red, green, and blue) you want to display.  %@NL@%
  10628. %@NL@%
  10629. Olivetti adapters (OCGA, OEGA, and OVGA) support the standard CGA, EGA, and
  10630. VGA modes (and palettes), plus an additional Olivetti mode described in
  10631. Section 10.2.2, "Olivetti Palettes."  %@NL@%
  10632. %@NL@%
  10633. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10634. NOTE
  10635.  
  10636. %@AI@%The distinction between a color index and a color value is important. A
  10637. %@AI@%color index is always a short integer. A color value is always a long
  10638. %@AI@%integer. The only exception to this rule involves %@AB@%_setbkcolor%@AE@%%@AI@%, which uses a
  10639. %@AI@%color index cast to a long integer in CGA and text modes.%@AE@%%@AE@%%@NL@%
  10640. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  10641. %@NL@%
  10642. %@NL@%
  10643. %@3@%%@CR:C6A00100012 @%%@AB@%10.2.1  CGA Palettes%@AE@%%@EH@%%@NL@%
  10644. %@NL@%
  10645. The CGA (Color Graphics Adapter) supports two color video modes: %@AB@%_MRES4COLOR%@AE@%
  10646. and %@AB@%_MRESNOCOLOR%@AE@%, which display four colors selected from one of several
  10647. predefined palettes of colors. They display these foreground colors against
  10648. a background color that can be any one of the 16 available colors. With the
  10649. CGA hardware, the palette of foreground colors is predefined and cannot be
  10650. changed. Each palette number is an integer. (See Table 10.4.)  %@NL@%
  10651. %@NL@%
  10652. %@AB@%Table 10.4  %@AB@%CGA Palettes in _MRES4COLOR Mode%@AE@%%@AE@%
  10653.  
  10654. %@TH:  14   585 04 16 14 16 30 @%
  10655.                               Color Index     
  10656. Palette         1             2               3
  10657. Number                                        
  10658. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10659. 0               Green         Red             Brown
  10660.  
  10661. 1               Cyan          Magenta         Light Gray
  10662.  
  10663. 2               Light Green   Light Red       Yellow
  10664.  
  10665. 3               Light Cyan    Light Magenta   White
  10666.  
  10667. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10668.  
  10669. %@TE:  14   585 04 16 14 16 30 @%
  10670.  
  10671. %@AU@% _MRESNOCOLOR produces palettes with shades of gray on monochrome monitors.%@AE@%
  10672. %@NL@%
  10673. %@NL@%
  10674. The %@AB@%_MRESNOCOLOR%@AE@% video mode produces palettes containing various shades of
  10675. gray on monochrome monitors. However, the %@AB@%_MRESNOCOLOR%@AE@% mode displays colors
  10676. when used with a color display. Only two palettes are available in this
  10677. mode. Table 10.5 shows the colors available in the two palettes.  %@NL@%
  10678. %@NL@%
  10679. %@AB@%Table 10.5  %@AB@%CGA Palettes in _MRESNOCOLOR Mode%@AE@%%@AE@%
  10680.  
  10681. %@TH:  10   463 04 16 13 14 33 @%
  10682.                              Color Index   
  10683. Palette         1            2             3
  10684. Number                                     
  10685. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10686. 0               Blue         Red           Light Gray
  10687.  
  10688. 1               Light Blue   Light Red     White
  10689.  
  10690. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10691.  
  10692. %@TE:  10   463 04 16 13 14 33 @%
  10693.  
  10694. You can use the %@AB@%_selectpalette%@AE@% function only in the %@AB@%_MRES4COLOR%@AE@%,
  10695. %@AB@%_MRESNOCOLOR%@AE@%, and %@AB@%_ORESCOLOR%@AE@% graphics modes. To change palettes in other
  10696. video modes, use the %@AB@%_remappalette%@AE@% or %@AB@%_remapallpalette%@AE@% functions.  %@NL@%
  10697. %@NL@%
  10698. %@NL@%
  10699. %@3@%%@CR:C6A00100013 @%%@AB@%10.2.2  Olivetti(R) Palettes%@AE@%%@EH@%%@NL@%
  10700. %@NL@%
  10701. Olivetti graphics adapters are found in most Olivetti computers (including
  10702. the M24, M28, M240, M280, and M380) and in the AT&T 6300 series computers.
  10703. These adapters function the same as their non-Olivetti equivalents; that is,
  10704. the OCGA, OEGA, and OVGA adapters support CGA, EGA, and VGA modes,
  10705. respectively. In addition, Olivetti adapters can enter the high resolution
  10706. %@AB@%_ORESCOLOR%@AE@% mode.  %@NL@%
  10707. %@NL@%
  10708. In %@AB@%_ORESCOLOR%@AE@% mode, you can choose one of 16 foreground colors by passing a
  10709. value in the range 0 -15 to the %@AB@%_selectpalette%@AE@% function. The background
  10710. color is always black.  %@NL@%
  10711. %@NL@%
  10712. %@NL@%
  10713. %@3@%%@CR:C6A00100014 @%%@AB@%10.2.3  VGA Palettes%@AE@%%@EH@%%@NL@%
  10714. %@NL@%
  10715. Depending on the video mode currently in effect, a VGA (Video Graphics
  10716. Array) screen has 2, 16, or 256 color indexes chosen from a pool of 262,144
  10717. (256K) color values.  %@NL@%
  10718. %@NL@%
  10719. To name a color value, specify a level of intensity ranging from 0 - 63 for
  10720. each of the red, green, and blue components. The long integer that defines a
  10721. color value contains four bytes (32 bits):  %@NL@%
  10722. %@NL@%
  10723. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10724. %@NL@%
  10725. The most-significant byte should contain zeros. The two high bits in the
  10726. remaining three bytes should also be zero (these bits are ignored).  %@NL@%
  10727. %@NL@%
  10728. To mix a light red (pink), turn red all the way up, and mix in some green
  10729. and blue:  %@NL@%
  10730. %@NL@%
  10731. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10732. %@NL@%
  10733. The number 0x0020203FL represents this value in hexadecimal notation. You
  10734. can also use the following macro:  %@NL@%
  10735. %@NL@%
  10736. %@AS@%  #define RGB ( r, g, b ) (0x3F3F3FL & ((long)(b) << 16 | (g) << 8 | (r)))%@AE@%%@NL@%
  10737. %@NL@%
  10738. To create pure yellow (100% red plus 100% green) and assign it to a variable
  10739. %@AS@% yel%@AE@%, use this line:  %@NL@%
  10740. %@NL@%
  10741. %@AS@%  yel = RGB( 63, 63, 0 );%@AE@%%@NL@%
  10742. %@NL@%
  10743. For white, turn all the colors on: %@AS@% RGB( 63, 63, 63)%@AE@%. For black, set all
  10744. colors to 0: %@AS@% RGB( 0, 0, 0 )%@AE@%. %@AS@%  %@AE@%%@NL@%
  10745. %@NL@%
  10746. Once you have the color value,  %@NL@%
  10747. %@NL@%
  10748. %@NL@%
  10749.   ■   Call %@AB@%_remappalette%@AE@%, passing a color index and a color value.%@NL@%
  10750. %@NL@%
  10751.   ■   Call %@AB@%_setcolor%@AE@% to make that color index the current color.%@NL@%
  10752. %@NL@%
  10753.   ■   Draw something.%@NL@%
  10754. %@NL@%
  10755. %@NL@%
  10756. The program YELLOW.C below shows how to remap a color. It draws a rectangle
  10757. in color index 3 and then changes index 3 to the color value 0x00003F3FL
  10758. (yellow).  %@NL@%
  10759. %@NL@%
  10760. %@AS@%  /* YELLOW.C -- Draws a yellow box on the screen */
  10761. %@AS@%  /* Requires VGA or EGA */
  10762. %@AS@%  
  10763. %@AS@%  #include <graph.h> /* graphics functions */
  10764. %@AS@%  #include <conio.h> /* getch */
  10765. %@AS@%  
  10766. %@AS@%  main()
  10767. %@AS@%  {
  10768. %@AS@%     short int index3 = 3;
  10769. %@AS@%     long int yellow = 0x00003F3FL;
  10770. %@AS@%     long int old3;%@AE@%%@NL@%
  10771. %@NL@%
  10772. %@AS@%  if( _setvideomode( _HRES16COLOR ) )
  10773. %@AS@%     {
  10774. %@AS@%              /* set current color to index 3*/
  10775. %@AS@%        _setcolor( index3 );
  10776. %@AS@%              /* draw a rectangle in that color */
  10777. %@AS@%        _rectangle( _GBORDER, 10, 10, 110, 110 );
  10778. %@AS@%              /* wait for a keypress */
  10779. %@AS@%        getch();
  10780. %@AS@%              /* change index 3 to yellow */
  10781. %@AS@%        old3 = _remappalette( index3, yellow );
  10782. %@AS@%              /* wait for a keypress */
  10783. %@AS@%        getch();
  10784. %@AS@%              /* restore the old color */
  10785. %@AS@%        _remappalette( index3, old3 );
  10786. %@AS@%        getch();
  10787. %@AS@%               /* back to default mode */
  10788. %@AS@%        _setvideomode( _DEFAULTMODE );
  10789. %@AS@%     } else _outtext( "This program requires EGA or VGA." );
  10790. %@AS@%  }%@AE@%%@NL@%
  10791. %@NL@%
  10792. %@NL@%
  10793. %@3@%%@CR:C6A00100015 @%%@AB@%10.2.4  MCGA Palettes%@AE@%%@EH@%%@NL@%
  10794. %@NL@%
  10795. In terms of color mixing, the MCGA (Multicolor Graphics Array) adapter is
  10796. the same as the VGA. It can display any of 256K colors. It cannot enter all
  10797. of the VGA video modes, however. It is limited to CGA modes and %@AB@%_VRES2COLOR%@AE@%
  10798. and %@AB@%_MRES256COLOR%@AE@%.  %@NL@%
  10799. %@NL@%
  10800. %@NL@%
  10801. %@3@%%@CR:C6A00100016 @%%@AB@%10.2.5  EGA Palettes%@AE@%%@EH@%%@NL@%
  10802. %@NL@%
  10803. Mixing colors in EGA (Enhanced Graphics Adapter) is similar to the VGA
  10804. mixing described in Section 10.2.3, but there are fewer levels of intensity
  10805. for the red, green, and blue (RGB) components. In the modes that offer 64
  10806. colors, the RGB values include two bits and can range in value from 0 - 3.
  10807. The long integer that defines a color value looks like this:  %@NL@%
  10808. %@NL@%
  10809. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10810. %@NL@%
  10811. The bits marked %@AS@% 0 %@AE@% should be zeros; the bits marked %@AS@% ? %@AE@% are ignored. EGA
  10812. color values are defined this way to maintain compatibility with VGA color
  10813. values.  %@NL@%
  10814. %@NL@%
  10815. To form a pure red color value, use the constant 0x00000030L. For cyan (blue
  10816. plus green), use 0x00303000L. The RGB macro defined above for VGA color
  10817. mixing can be used as is, or you can modify it for EGA monitors:  %@NL@%
  10818. %@NL@%
  10819. %@AS@%  #define EGARGB( r, g, b ) (0x303030L & ((long)(b) << 20 | (g) << 12 | (r
  10820. %@AS@%  << 4)))%@AE@%%@NL@%
  10821. %@NL@%
  10822. In this macro, you would pass values in the range 0 -3 instead of 0 - 63.  %@NL@%
  10823. %@NL@%
  10824. For an example program that remaps a color index to a color value, see
  10825. YELLOW.C in Section 10.2.3, "VGA Palettes."  %@NL@%
  10826. %@NL@%
  10827. %@NL@%
  10828. %@3@%%@CR:C6A00100017 @%%@AB@%10.2.6  Symbolic Constants%@AE@%%@EH@%%@NL@%
  10829. %@NL@%
  10830. The GRAPH.H file defines the following constants, which can be used as
  10831. ready-made color values for EGA and VGA adapters:  %@NL@%
  10832. %@NL@%
  10833. %@TH:   7   448 01 14 15 47 @%
  10834. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10835. %@AB@%_BLACK%@AE@%        _GREEN         %@AB@%_LIGHTYELLOW%@AE@%
  10836. %@AB@%_BLUE%@AE@%         _LIGHTBLUE     %@AB@%_MAGENTA%@AE@%
  10837. %@AB@%_BRIGHTWHITE%@AE@%  _LIGHTCYAN     %@AB@%_RED%@AE@%
  10838. %@AB@%_BROWN%@AE@%        _LIGHTGREEN    %@AB@%_WHITE%@AE@%
  10839. %@AB@%_CYAN%@AE@%         _LIGHTMAGENTA
  10840. %@AB@%_GRAY%@AE@%         _LIGHTRED
  10841. %@TE:   7   448 01 14 15 47 @%
  10842.  
  10843. For example, to change color index 1 to red, use the line%@AB@%  %@AE@%%@NL@%
  10844. %@NL@%
  10845. %@AS@%  _remappalette( 1, _RED );%@AE@%%@NL@%
  10846. %@NL@%
  10847. which causes any object currently drawn with color index 1 to change to red.
  10848. The default color value associated with index 1 is blue.  %@NL@%
  10849. %@NL@%
  10850. %@NL@%
  10851. %@2@%%@CR:C6A00100018 @%%@AB@%10.3  Specifying Points within Coordinate Systems%@AE@%%@EH@%%@NL@%
  10852. %@NL@%
  10853. A coordinate system describes points on the screen in terms of their
  10854. horizontal (%@AI@%x%@AE@%) and vertical (%@AI@%y%@AE@%) positions. You specify a certain location by
  10855. providing two values that map to a unique position.%@CR:C6A00100019 @%%@AI@%  %@AE@%%@NL@%
  10856. %@NL@%
  10857. %@AU@% Graphics functions usually use viewport and window coordinates.%@AE@%  %@NL@%
  10858. %@NL@%
  10859. Coordinates on the physical screen never change. Only five functions, listed
  10860. in Section 10.3.1, use physical coordinates. All other graphics functions
  10861. use one of these two coordinate systems:  %@NL@%
  10862. %@NL@%
  10863. %@NL@%
  10864.   ■   Viewport coordinates (short integers)%@NL@%
  10865. %@NL@%
  10866.   ■   Window coordinates (double-precision floating-point numbers)%@NL@%
  10867. %@NL@%
  10868. %@NL@%
  10869. Viewports and windows can occupy all of the physical screen or just part of
  10870. it. The three coordinate systems and conventions for naming points and
  10871. regions of the screen are described below.  %@NL@%
  10872. %@NL@%
  10873. %@NL@%
  10874. %@3@%%@CR:C6A00100020 @%%@AB@%10.3.1  Physical Coordinates%@AE@%%@EH@%%@NL@%
  10875. %@NL@%
  10876. Within the physical screen, the upper left corner is called the "origin."
  10877. The %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates for the origin are always (0, 0). The %@AI@%x%@AE@% axis extends
  10878. in the positive direction left to right, while the %@AI@%y%@AE@% axis extends in the
  10879. positive direction top to bottom.%@CR:C6A00100021 @%  %@NL@%
  10880. %@NL@%
  10881. For example, the video mode %@AB@%_VRES16COLOR%@AE@% has a resolution of 640 x 480,
  10882. which means the %@AI@%x%@AE@% axis contains the values 0 - 639 (left to right), and the
  10883. %@AI@%y%@AE@% axis contains 0 - 479 (top to bottom). (See Figure 10.1.)  %@NL@%
  10884. %@NL@%
  10885. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10886. %@NL@%
  10887. Only five functions use physical coordinates: %@AB@%_setcliprgn%@AE@%, %@AB@%_setvieworg%@AE@%,
  10888. %@AB@%_setviewport%@AE@%,%@AB@% _getviewcoord%@AE@%, and%@AB@% _getphyscoord%@AE@%.  %@NL@%
  10889. %@NL@%
  10890. The %@AB@%_setcliprgn%@AE@% function establishes a "clipping region." Attempts to draw
  10891. inside the region succeed, while attempts to draw outside the region are
  10892. clipped (ignored). When you first enter a graphics mode, the clipping region
  10893. defaults to the entire screen.  %@NL@%
  10894. %@NL@%
  10895. The %@AB@%_setvieworg%@AE@% function changes the current location of the origin. When a
  10896. program first enters a graphics mode, the physical origin and the viewport
  10897. origin are in the upper left corner. The following code moves the viewport
  10898. origin to the physical screen location (50, 100):%@CR:C6A00100022 @%  %@NL@%
  10899. %@NL@%
  10900. %@AS@%  _setvieworg( 50, 100 );%@AE@%%@NL@%
  10901. %@NL@%
  10902. The effect on the screen is illustrated in Figure 10.2. Note that the number
  10903. of pixels remains constant, but the range of legal %@AI@%x%@AE@% values changes from a
  10904. range of 0 to 639 (physical screen) to -50 to 589. The legal %@AI@%y%@AE@% values change
  10905. as well.  %@NL@%
  10906. %@NL@%
  10907. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10908. %@NL@%
  10909. All graphics functions are affected by the new origin, including %@AB@%_arc%@AE@%,
  10910. %@AB@%_ellipse%@AE@%, %@AB@%_lineto%@AE@%, %@AB@%_moveto%@AE@%, %@AB@%_outgtext%@AE@%,%@AB@% %@AE@% %@AB@%_pie%@AE@%, and %@AB@%_rectangle%@AE@%.  %@NL@%
  10911. %@NL@%
  10912. The third function that uses physical coordinates is %@AB@%_setviewport%@AE@%, described
  10913. below, which establishes the boundaries of the current viewport.  %@NL@%
  10914. %@NL@%
  10915. %@NL@%
  10916. %@3@%%@CR:C6A00100023 @%%@AB@%10.3.2  Viewport Coordinates%@AE@%%@EH@%%@NL@%
  10917. %@NL@%
  10918. The default viewport coordinate system is identical to the physical screen
  10919. coordinate system. The %@AB@%_setviewport%@AE@% function creates a new viewport within
  10920. the boundaries of the physical screen. A standard viewport has two
  10921. distinguishing features:%@CR:C6A00100024 @%%@CR:C6A00100025 @%  %@NL@%
  10922. %@NL@%
  10923. %@NL@%
  10924.   ■   The origin of a viewport initially lies in the upper left corner of
  10925.       the viewport, not the upper left corner of the physical screen.%@NL@%
  10926. %@NL@%
  10927.   ■   The clipping region matches the outer boundaries of the viewport.%@NL@%
  10928. %@NL@%
  10929. %@NL@%
  10930. %@AU@% Graphics output functions require viewport or window coordinate values.%@AE@%  %@NL@%
  10931. %@NL@%
  10932. In other words, the %@AB@%_setviewport%@AE@% function does the same thing as would two
  10933. separate calls to %@AB@%_setvieworg%@AE@% and %@AB@%_setcliprgn%@AE@%. All graphics output functions
  10934. require values that are either viewport coordinates or window coordinates.  %@NL@%
  10935. %@NL@%
  10936. For example,  %@NL@%
  10937. %@NL@%
  10938. %@AS@%  _setviewport( 50, 50, 200, 100 );%@AE@%%@NL@%
  10939. %@NL@%
  10940. creates the viewport illustrated in Figure 10.3. The values passed to the
  10941. %@AB@%_setviewport%@AE@% function are physical screen locations of opposite corners.
  10942. After the viewport is created, the viewport origin lies in the upper left
  10943. corner.  %@NL@%
  10944. %@NL@%
  10945. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10946. %@NL@%
  10947. %@NL@%
  10948. %@3@%%@CR:C6A00100026 @%%@AB@%10.3.3  Window Coordinates%@AE@%%@EH@%%@NL@%
  10949. %@NL@%
  10950. The %@AB@%_setwindow%@AE@% function allows you to use floating-point coordinates instead
  10951. of integers. More importantly, it scales the screen coordinates to almost
  10952. any size within the current viewport. Window functions take double-precision
  10953. arguments and have names that end with the suffixes %@AB@%_w%@AE@% or %@AB@%_wxy%@AE@%. The function
  10954. %@AB@%_lineto_w%@AE@% is the window-coordinate equivalent of the viewport function
  10955. %@AB@%_lineto%@AE@%.%@CR:C6A00100027 @%  %@NL@%
  10956. %@NL@%
  10957. To create a window for charting 12 months of average temperatures ranging
  10958. from - 40 to 100, use this line:  %@NL@%
  10959. %@NL@%
  10960. %@AS@%  _setwindow( TRUE, 1.0, -40.0, 12.0, 100.0 );%@AE@%%@NL@%
  10961. %@NL@%
  10962. The first argument is the invert flag, which puts the lowest %@AI@%y%@AE@% value at the
  10963. bottom of the screen instead of the top. The minimum and maximum coordinates
  10964. follow. The new organization of the screen is shown in Figure 10.4.  %@NL@%
  10965. %@NL@%
  10966. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10967. %@NL@%
  10968. If you plot a point with %@AB@%_setpixel_w%@AE@% or draw a line with %@AB@%_lineto_w%@AE@%, the
  10969. values are automatically scaled to the established window.  %@NL@%
  10970. %@NL@%
  10971. Window-coordinate graphics provide a lot of flexibility. You can fit an axis
  10972. into a small range (such as 151.25 to 151.45) or into a large range (-50,000
  10973. to 80,000), depending on the type of data to be graphed. In addition, by
  10974. changing the window coordinates and redrawing a figure, you can create the
  10975. effects of zooming in or panning across a figure.  %@NL@%
  10976. %@NL@%
  10977. %@NL@%
  10978. %@3@%%@CR:C6A00100028 @%%@AB@%10.3.4  Screen Locations%@AE@%%@EH@%%@NL@%
  10979. %@NL@%
  10980. A coordinate system needs two values (a horizontal and a vertical position)
  10981. to describe the location of a point on the screen. There are times, however,
  10982. when it is more convenient to use one variable instead of two.%@CR:C6A00100029 @%%@CR:C6A00100030 @%  %@NL@%
  10983. %@NL@%
  10984. Some graphics functions require you to pass the location of a point on the
  10985. screen. Others return a value that represents a location. The GRAPH.H file
  10986. defines two structures that allow you to refer to a point with a single
  10987. variable.  %@NL@%
  10988. %@NL@%
  10989. %@NL@%
  10990.   ■   An %@AB@%xycoord %@AE@%structure contains two short integers called %@AB@%xcoord %@AE@%and
  10991.       %@AB@%ycoord%@AE@% for use in viewport graphics.%@NL@%
  10992. %@NL@%
  10993.   ■   A %@AB@%_wxycoord %@AE@%structure contains two %@AB@%doubles%@AE@% called %@AB@%wx %@AE@%and %@AB@%wy %@AE@%for use in
  10994.       window-coordinate graphics.%@NL@%
  10995. %@NL@%
  10996. %@NL@%
  10997. For example, you pass four %@AB@%doubles%@AE@% to the %@AB@%_rectangle_w%@AE@% function: an %@AI@%x%@AE@% and %@AI@%y%@AE@%
  10998. position for the upper left corner of the window and an %@AI@%x%@AE@% and %@AI@%y%@AE@% position for
  10999. the lower right corner. The %@AB@%_rectangle_wxy%@AE@% function takes two %@AB@%_wxycoord%@AE@%
  11000. structures.  %@NL@%
  11001. %@NL@%
  11002. %@NL@%
  11003. %@3@%%@CR:C6A00100031 @%%@AB@%10.3.5  Bounding Rectangles%@AE@%%@EH@%%@NL@%
  11004. %@NL@%
  11005. Certain figures such as arcs and ellipses are centered within a "bounding
  11006. rectangle," specified by two points that define the opposite corners of the
  11007. rectangle. The center of the rectangle becomes the center of the figure, and
  11008. the rectangle's borders determine the size of the figure. Figure 10.5 shows
  11009. start and end vectors and a bounding rectangle in which a pie shape has been
  11010. drawn with the %@AB@%_pie%@AE@% function. The first two sets of coordinates are %@AI@%x1%@AE@%, %@AI@%y1%@AE@%,
  11011. %@AI@%x2%@AE@%, and %@AI@%y2%@AE@%. They define the boundaries of the rectangle. The pie shape needs
  11012. two other points, %@AI@%x3%@AE@%, %@AI@%y3%@AE@%, %@AI@%x4%@AE@%, and %@AI@%y4%@AE@%, which indicate the starting and ending
  11013. lines.  %@NL@%
  11014. %@NL@%
  11015. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  11016. %@NL@%
  11017. %@NL@%
  11018. %@3@%%@CR:C6A00100032 @%%@AB@%10.3.6  The Pixel Cursor%@AE@%%@EH@%%@NL@%
  11019. %@NL@%
  11020. A "pixel cursor" is a location on the screen. The %@AB@%_moveto%@AE@% function positions
  11021. this cursor at a given spot. Nothing visible appears. If you call %@AB@%_lineto%@AE@%, a
  11022. line is drawn from the current pixel cursor to another point. The %@AB@%_lineto%@AE@%
  11023. function also changes the location of the pixel cursor. When you call
  11024. %@AB@%_outgtext%@AE@% to display fonted text, the characters are drawn at the current
  11025. pixel cursor location.  %@NL@%
  11026. %@NL@%
  11027. To draw a series of connected lines, call %@AB@%_lineto%@AE@% several times.  %@NL@%
  11028. %@NL@%
  11029. The %@AB@%_getcurrentposition%@AE@% function returns the cursor location in an %@AB@%xycoord%@AE@%
  11030. structure.  %@NL@%
  11031. %@NL@%
  11032. %@NL@%
  11033. %@2@%%@CR:C6A00100033 @%%@AB@%10.4  Graphics Functions%@AE@%%@EH@%%@NL@%
  11034. %@NL@%
  11035. This section lists the functions that work in one or more bit-mapped
  11036. graphics modes. Most of these functions are present in several forms. The
  11037. function names that end with %@AB@%_w%@AE@% use %@AB@%double%@AE@% values as arguments and the
  11038. window coordinate system. Functions that end with %@AB@%_wxy%@AE@% use the window
  11039. coordinate system and a %@AB@%_wxycoord%@AE@% structure to define the coordinates.
  11040. Functions with no suffix use the viewport coordinate system.%@CR:C6A00100034 @%  %@NL@%
  11041. %@NL@%
  11042. %@NL@%
  11043. %@3@%%@CR:C6A00100035 @%%@AB@%10.4.1  Controlling Video Modes%@AE@%%@EH@%%@NL@%
  11044. %@NL@%
  11045. The functions described below affect the current video mode, coordinate
  11046. systems, clipping regions, viewports, and windows. For more information, use
  11047. on-line help.  %@NL@%
  11048. %@NL@%
  11049. %@AB@%_clearscreen%@AE@% - Erases the text or graphics screen and fills it with the
  11050. current background color (note that setting the video mode automatically
  11051. clears the screen). Pass one of the constants %@AB@%_GCLEARSCREEN%@AE@%, %@AB@%_GVIEWPORT%@AE@%, or
  11052. %@AB@%_GWINDOW%@AE@%. No return value.%@NL@%
  11053. %@NL@%
  11054. %@AB@%_getphyscoord%@AE@% - Converts viewport coordinates to physical coordinates. Pass
  11055. an %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinate from the viewport. The function returns an %@AB@%xycoord%@AE@%
  11056. structure, which includes an %@AI@%x%@AE@% and a %@AI@%y%@AE@% position from the physical screen.%@CR:C6A00100036 @%%@NL@%
  11057. %@NL@%
  11058. %@AB@%_getvideoconfig%@AE@% - Obtains the status of the current graphics environment.
  11059. Pass it the address of a structure of type %@AB@%_videoconfig%@AE@%. See Section 10.1.3.
  11060. "Reading the videoconfig Structure."%@NL@%
  11061. %@NL@%
  11062. %@AB@%_getviewcoord%@AE@% - Converts physical coordinates to viewport coordinates. Pass
  11063. two integers: an %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinate. The function returns an %@AB@%xycoord%@AE@%
  11064. structure containing the equivalent position within the viewport.%@NL@%
  11065. %@NL@%
  11066. %@AB@%_getviewcoord_w%@AE@% - Converts window coordinates to viewport coordinates. Pass
  11067. two %@AB@%doubles%@AE@% that name points within the window. Returns the equivalent
  11068. viewport coordinates as an %@AB@%xycoord%@AE@% structure.%@NL@%
  11069. %@NL@%
  11070. %@AB@%_getviewcoord_wxy%@AE@% - Converts window coordinates to viewport coordinates in
  11071. an %@AB@%xycoord%@AE@% structure. Pass a %@AB@%_wxycoord%@AE@% structure.%@NL@%
  11072. %@NL@%
  11073. %@AB@%_getwindowcoord%@AE@% - Converts viewport coordinates to window coordinates. Pass
  11074. two integers representing viewport coordinates. Returns a %@AB@%_wxycoord%@AE@%
  11075. structure.%@NL@%
  11076. %@NL@%
  11077. %@AB@%_setcliprgn%@AE@% - Limits graphic output to part of the screen, called the
  11078. "clipping  region." Pass four values: the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinate of the upper
  11079. left corner (on the physical screen) and the coordinates of the lower right
  11080. corner. The default clipping region is the entire screen. See Section
  11081. 10.3.1, "Physical Coordinates."%@NL@%
  11082. %@NL@%
  11083. %@AB@%_setvideomode%@AE@% - Selects an operating mode for the display screen. Pass a
  11084. constant, such as %@AB@%_HRES16COLOR%@AE@%. Returns 0 if the video mode selected is not
  11085. supported by the hardware. See Section 10.1.2, "Setting a Video Mode."%@NL@%
  11086. %@NL@%
  11087. %@AB@%_setvideomoderows%@AE@% - Sets the video mode and the number of rows for text
  11088. operations. Pass two values: a video mode and the desired number of text
  11089. rows (25, 30, 43, 50, or 60). Pass the symbolic constant %@AB@%_MAXTEXTROWS%@AE@% to get
  11090. the largest available number of rows. Returns the number of rows or 0 if
  11091. unsuccessful.%@NL@%
  11092. %@NL@%
  11093. %@AB@%_setvieworg%@AE@% - Repositions the viewport origin. Pass an %@AI@%x%@AE@% and %@AI@%y%@AE@% position: the
  11094. physical screen location that will become the new origin. Returns the
  11095. previous origin in an %@AB@%xycoord%@AE@% structure.%@NL@%
  11096. %@NL@%
  11097. %@AB@%_setviewport%@AE@% - Creates a viewport, including a clipping region and a new
  11098. origin in the upper left corner of the viewport. Subsequent calls to
  11099. graphics routines will be limited to the viewport area. Pass four short
  11100. integers that indicate the physical screen locations of the %@AI@%x%@AE@% and %@AI@%y%@AE@%
  11101. coordinates in the upper left and  lower right corners of the viewport. No
  11102. return value.%@NL@%
  11103. %@NL@%
  11104. %@AB@%_setwindow%@AE@% - Defines a window coordinate system. Pass five values: a short
  11105. invert flag (TRUE or FALSE) and four %@AB@%doubles%@AE@% that represent the extreme
  11106. values in the upper left and lower right portions of the current viewport.
  11107. See Section 10.3.3, "Window Coordinates."%@NL@%
  11108. %@NL@%
  11109. %@NL@%
  11110. %@3@%%@CR:C6A00100037 @%%@AB@%10.4.2  Changing Colors%@AE@%%@EH@%%@NL@%
  11111. %@NL@%
  11112. The functions below control colors and color palettes. For an introduction
  11113. to this topic, see Section 10.2, "Mixing Colors and Changing Palettes." For
  11114. function prototypes and more information, consult on-line help.%@CR:C6A00100038 @%%@CR:C6A00100039 @%  %@NL@%
  11115. %@NL@%
  11116. %@AB@%_getbkcolor%@AE@% - Reports the current background color as a long integer. In
  11117. EGA, MCGA, and VGA video modes, this is a color value. In CGA and text
  11118. modes, it is a color index.%@NL@%
  11119. %@NL@%
  11120. %@AB@%_getcolor%@AE@% - Returns the current color index.%@NL@%
  11121. %@NL@%
  11122. %@AB@%_remapallpalette%@AE@% - Assigns new color values to all color indexes. Pass a
  11123. pointer to an array of color values. Returns 0 if unsuccessful.%@NL@%
  11124. %@NL@%
  11125. %@AB@%_remappalette%@AE@% - Assigns a color value to a specific color index. Pass a
  11126. short color index and a long color value (which specifies the amount of red,
  11127. green, and blue). Returns the previous color value for that index or -1 if
  11128. unsuccessful. See Section 10.2.1, "CGA Palettes."%@NL@%
  11129. %@NL@%
  11130. %@AB@%_selectpalette%@AE@% - Selects a predefined palette. This function applies only to
  11131. the CGA video modes %@AB@%_MRES4COLOR%@AE@% and %@AB@%_MRESNOCOLOR%@AE@% and the Olivetti graphics
  11132. mode%@AB@% _ORESCOLOR%@AE@%. To change palettes in other color video modes, use
  11133. %@AB@%_remappalette%@AE@% instead. Pass a short integer in the range 0 - 4 for CGA, or 0
  11134. -15 for Olivetti mode. Returns the value of the previous palette.%@NL@%
  11135. %@NL@%
  11136. %@AB@%_setbkcolor%@AE@% - Sets the current background color. Always pass a long integer.
  11137. In EGA, MCGA, and VGA modes, this value is a color value. In CGA and text
  11138. modes, this is a color index cast to a long integer. Returns the old
  11139. background color or -1 if unsuccessful.%@NL@%
  11140. %@NL@%
  11141. %@AB@%_setcolor%@AE@% - Sets the color index to be used for graphic output. It affects
  11142. later calls to functions such as %@AB@%_arc%@AE@%, %@AB@%_ellipse%@AE@%, %@AB@%_floodfill%@AE@%, %@AB@%_lineto%@AE@%,
  11143. %@AB@%_outgtext%@AE@%, %@AB@%_outtext%@AE@%, %@AB@%_pie%@AE@%, %@AB@%_rectangle%@AE@%, and %@AB@%_setpixel%@AE@%. Returns the previous
  11144. color or -1 if unsuccessful.%@NL@%
  11145. %@NL@%
  11146. %@NL@%
  11147. %@3@%%@CR:C6A00100040 @%%@AB@%10.4.3  Drawing Points, Lines, and Shapes%@AE@%%@EH@%%@NL@%
  11148. %@NL@%
  11149. The functions described below draw points, lines, and shapes. For a
  11150. definition of bounding rectangle and pixel cursor, see Sections 10.3.5 and
  11151. 10.3.6.%@CR:C6A00100041 @%  %@NL@%
  11152. %@NL@%
  11153. %@AB@%_arc%@AE@% - Draws an elliptical arc. Pass eight short integers: four pairs of %@AI@%x%@AE@%
  11154. and %@AI@%y%@AE@% coordinates. The first two pairs are the corners of the bounding
  11155. rectangle. The third and fourth are the starting and ending points of the
  11156. arc. Returns 0 if unsuccessful.%@NL@%
  11157. %@NL@%
  11158. %@AB@%_arc_wxy%@AE@% - Draws an arc within the window. Pass four %@AB@%wxycoord%@AE@% structures.
  11159. The first two are the corners of the bounding rectangle. The third and
  11160. fourth are the starting and ending points of the arc. Returns 0 if
  11161. unsuccessful.%@NL@%
  11162. %@NL@%
  11163. %@AB@%_ellipse%@AE@% - Draws an ellipse or a circle. Pass a short fill flag (%@AB@% _GBORDER%@AE@%
  11164. or %@AB@%_GFILLINTERIOR%@AE@%) and four short integers representing the corners of the
  11165. bounding rectangle. Returns 0 if unsuccessful.%@NL@%
  11166. %@NL@%
  11167. %@AB@%_ellipse_w%@AE@% - Draws an ellipse or a circle within a window. Pass a short fill
  11168. flag (%@AB@% _GBORDER%@AE@% or %@AB@%_GFILLINTERIOR%@AE@%) and four %@AB@%doubles%@AE@% representing the corners
  11169. of the bounding rectangle. Returns 0 if unsuccessful.%@NL@%
  11170. %@NL@%
  11171. %@AB@%_ellipse_wxy%@AE@% - Draws an ellipse or a circle. Pass a short fill flag (%@AB@%
  11172. %@AB@%_GBORDER%@AE@% or  %@AB@%_GFILLINTERIOR%@AE@%) and two %@AB@%_wxycoord%@AE@% structures representing the
  11173. two corners of the bounding rectangle. Returns 0 if unsuccessful.%@NL@%
  11174. %@NL@%
  11175. %@AB@%_getcurrentposition%@CR:C6A00100042 @%%@AE@% - Returns the current pixel cursor position in viewport
  11176. coordinates as an %@AB@%xycoord%@AE@% structure. The current position can be changed by
  11177. %@AB@%_arc%@AE@%, %@AB@%_lineto%@AE@%, and %@AB@%_moveto%@AE@%. The default position is the center of the
  11178. viewport.%@NL@%
  11179. %@NL@%
  11180. %@AB@%_getcurrentposition_w%@AE@% - Returns the current position of the pixel cursor as
  11181. a %@AB@%_wxycoord%@AE@% structure containing the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates. Pass nothing.%@NL@%
  11182. %@NL@%
  11183. %@AB@%_getpixel%@AE@% - Returns a pixel's color index. Pass a short %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinate
  11184. (in viewport coordinates). If the point is outside the clipping region, the
  11185. function returns -1.%@NL@%
  11186. %@NL@%
  11187. %@AB@%_getpixel_w%@AE@% - Returns a pixel's color index. Pass two doubles: an %@AI@%x%@AE@% and %@AI@%y%@AE@%
  11188. coordinate.%@NL@%
  11189. %@NL@%
  11190. %@AB@%_lineto%@AE@% - Draws a line from the current pixel cursor position to a specified
  11191. point. Pass a short %@AI@%x%@AE@% and a short %@AI@%y%@AE@% position. Returns 0 if unsuccessful.%@NL@%
  11192. %@NL@%
  11193. %@AB@%_lineto_w%@AE@% - Draws a line from the current pixel position to a specified
  11194. window coordinate point. Pass a %@AB@%double%@AE@% %@AI@%x%@AE@% and %@AI@%y%@AE@% position. Returns 0 if
  11195. unsuccessful.%@NL@%
  11196. %@NL@%
  11197. %@AB@%_moveto%@AE@% - Moves the pixel cursor to a specified point (with no graphic
  11198. output). Pass an %@AI@%x%@AE@% and %@AI@%y%@AE@% position. Returns the coordinates of the previous
  11199. position in an %@AB@%xycoord%@AE@% structure.%@NL@%
  11200. %@NL@%
  11201. %@AB@%_moveto_w%@AE@% - Moves the pixel cursor to a specified point in a window. Pass
  11202. two doubles: an %@AI@%x%@AE@% and a %@AI@%y%@AE@% coordinate. Returns the previous position as a
  11203. %@AB@%_wxycoord%@AE@% structure.%@NL@%
  11204. %@NL@%
  11205. %@AB@%_ pie%@AE@% - Draws a figure shaped like a pie slice. Pass a short fill flag and
  11206. eight short integers. The first four describe the bounding rectangle. The
  11207. final four represent the starting vector and ending vector. Returns 0 if
  11208. unsuccessful.%@NL@%
  11209. %@NL@%
  11210. %@AB@%_ pie_wxy%@AE@% - Draws a pie-slice figure within a window. Pass a short fill flag
  11211. and four %@AB@%_wxycoord%@AE@% structures. The first two describe the bounding
  11212. rectangle. The second two represent the starting vector and ending vector.
  11213. Returns 0 if unsuccessful.%@NL@%
  11214. %@NL@%
  11215. %@AB@%_rectangle%@AE@% - Draws a rectangle in the current line style. Pass a short fill
  11216. flag (%@AB@% _GFILLINTERIOR%@AE@% or %@AB@%_GBORDER%@AE@%) and four short integers: the %@AI@%x%@AE@% and %@AI@%y%@AE@%
  11217. coordinates of opposite corners. Returns 0 if unsuccessful.%@NL@%
  11218. %@NL@%
  11219. %@AB@%_rectangle_w%@AE@% - Draws a rectangle in the current line style. Pass a short
  11220. fill flag (%@AB@% _GFILLINTERIOR%@AE@% or %@AB@%_GBORDER%@AE@%) and four doubles: the %@AI@%x%@AE@% and %@AI@%y%@AE@% window
  11221. coordinates of opposite corners. Returns 0 if unsuccessful.%@NL@%
  11222. %@NL@%
  11223. %@AB@%_rectangle_wxy%@AE@% - Draws a rectangle in the current line style. Pass a short
  11224. fill flag (%@AB@% _GFILLINTERIOR%@AE@% or %@AB@%_GBORDER%@AE@%) and two %@AB@%_wxycoord%@AE@% structures
  11225. describing the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates of opposite corners. Returns 0 if
  11226. unsuccessful.%@NL@%
  11227. %@NL@%
  11228. %@AB@%_setpixel%@AE@% - Sets a pixel to the current color (which is selected by
  11229. %@AB@%_setcolor%@AE@%). Pass it integer %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates. Returns the previous value
  11230. of the pixel or -1 if unsuccessful.%@NL@%
  11231. %@NL@%
  11232. %@AB@%_setpixel_w%@AE@% - Sets a pixel to the current color (which is selected by
  11233. %@AB@%_setcolor%@AE@%). Pass it %@AB@%double%@AE@% %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates describing a position within
  11234. the window. Returns the previous value of the pixel or -1 if unsuccessful.%@NL@%
  11235. %@NL@%
  11236. %@NL@%
  11237. %@3@%%@CR:C6A00100043 @%%@AB@%10.4.4  Defining Patterns%@AE@%%@EH@%%@NL@%
  11238. %@NL@%
  11239. The following functions control the style in which straight lines are drawn
  11240. and the fill pattern used for solid shapes. For more information, use
  11241. on-line help.%@CR:C6A00100044 @%  %@NL@%
  11242. %@NL@%
  11243. %@AB@%_floodfill%@AE@% - Fills a bounded shape with the fill pattern set by %@AB@%_setfillmask%@AE@%
  11244. in the current color established by %@AB@%_setcolor%@AE@%. Pass an %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinate
  11245. and a boundary color (the color index that marks the edge of the shape to be
  11246. filled). Returns 0 if unsuccessful.%@NL@%
  11247. %@NL@%
  11248. %@AB@%_floodfill_w%@AE@% - Fills a bounded shape with the fill pattern set by
  11249. %@AB@%_setfillmask%@AE@%. Pass %@AB@%doubles%@AE@% that describe an %@AI@%x%@AE@% and %@AI@%y%@AE@% position within the
  11250. window and a boundary color (the color index that marks the edge of the
  11251. shape to be filled). Returns 0 if unsuccessful.%@NL@%
  11252. %@NL@%
  11253. %@AB@%_getfillmask%@AE@% - Returns the address of the current fill mask, an
  11254. eight-character array, or 0 if the fill mask is not currently defined.%@NL@%
  11255. %@NL@%
  11256. %@AB@%_getlinestyle%@AE@% - Returns the line style, a short integer whose bits
  11257. correspond to the screen pixels turned on or off within a line.%@NL@%
  11258. %@NL@%
  11259. %@AB@%_setfillmask%@AE@% - Sets the current fill mask used by %@AB@%_floodfill %@AE@%and functions
  11260. that draw solid shapes (%@AB@%_ellipse%@AE@%, %@AB@%_pie%@AE@%, and %@AB@%_rectangle%@AE@%). Pass the address of
  11261. an array of eight unsigned characters, where each bit represents a pixel.
  11262. The pixels are drawn in the current color. No return value.%@NL@%
  11263. %@NL@%
  11264. %@AB@%_setlinestyle%@AE@% - Sets the current style, which is used to draw the straight
  11265. lines within %@AB@%_lineto%@AE@%, %@AB@%_rectangle%@AE@%, and %@AB@%_pie%@AE@%. Pass an unsigned short integer
  11266. within which the bits correspond to the pixels on screen. For example,
  11267. 0xFFFF represents a solid line, 0xAAAA is a dotted line, and 0xF0F0 is
  11268. dashed.%@NL@%
  11269. %@NL@%
  11270. %@NL@%
  11271. %@3@%%@CR:C6A00100045 @%%@AB@%10.4.5  Manipulating Images%@AE@%%@EH@%%@NL@%
  11272. %@NL@%
  11273. The functions described below can be used to create animated graphics. The
  11274. %@AB@%_getimage %@AE@%and %@AB@%_putimage %@AE@%functions act like a rubber stamp; after capturing a
  11275. shape, you can make copies anywhere on the screen.%@CR:C6A00100046 @%  %@NL@%
  11276. %@NL@%
  11277. %@AB@%_getimage%@AE@% - Stores a screen image in memory. Pass four integers (the
  11278. coordinates of the bounding rectangle) and a pointer to a storage buffer.
  11279. Call %@AB@%_imagesize%@AE@% to find out how much memory is required. No return value.%@NL@%
  11280. %@NL@%
  11281. %@AB@%_getimage_w%@AE@% - Stores a screen image in memory. Pass four %@AB@%doubles%@AE@% (the
  11282. coordinates of the bounding rectangle) and a pointer to a storage buffer.
  11283. Call %@AB@%_imagesize_w%@AE@% to find out how much memory is required. No return value.%@NL@%
  11284. %@NL@%
  11285. %@AB@%_getimage_wxy%@AE@% - Same as %@AB@%_getimage_w%@AE@%, but you pass two %@AB@%_wxycoord%@AE@% structures
  11286. and a pointer to memory.%@NL@%
  11287. %@NL@%
  11288. %@AB@%_imagesize%@AE@% - Returns a long integer representing the size of an image in
  11289. bytes. Call this function in preparation for a call to %@AB@%_getimage%@AE@%. Pass four
  11290. integers: the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates of opposite corners of the portion of the
  11291. screen to be saved.%@NL@%
  11292. %@NL@%
  11293. %@AB@%_imagesize_w%@AE@% - Returns the size of an image in bytes in preparation for a
  11294. call to %@AB@%_getimage_w%@AE@% and %@AB@%_putimage_w%@AE@%. Pass four doubles: the %@AI@%x%@AE@% and %@AI@%y%@AE@% window
  11295. coordinates of opposite corners of the portion of the screen to be saved.%@NL@%
  11296. %@NL@%
  11297. %@AB@%_imagesize_wxy%@AE@% - Same as %@AB@%_imagesize_w%@AE@%, but you pass two %@AB@%_wxycoord%@AE@%
  11298. structures.%@NL@%
  11299. %@NL@%
  11300. %@AB@%_putimage%@AE@% - Retrieves an image from memory and displays it on the active
  11301. screen page. The image should previously have been saved to memory with
  11302. %@AB@%_getimage%@AE@%. Pass two short integers (coordinates where the image is to be
  11303. placed), a pointer to the image, and a short integer indicating what kind of
  11304. action to take: %@AB@%_GAND%@AE@%, %@AB@%_GOR%@AE@%, %@AB@%_GPRESET%@AE@%, %@AB@%_GPSET%@AE@%, or %@AB@%_GXOR%@AE@%. No return value.%@NL@%
  11305. %@NL@%
  11306. %@AB@%_putimage_w%@AE@% - Displays an image from memory within a window. The image
  11307. should previously have been saved to memory with %@AB@%_getimage_w%@AE@%. Pass two
  11308. %@AB@%doubles%@AE@% (coordinates where the image is to be placed), a pointer to the
  11309. image, and a short integer indicating what kind of action to take: %@AB@%_GAND%@AE@%,
  11310. %@AB@%_GOR%@AE@%, %@AB@%_GPRESET%@AE@%, %@AB@%_GPSET%@AE@%, or %@AB@%_GXOR%@AE@%. No return value.%@NL@%
  11311. %@NL@%
  11312. %@NL@%
  11313. %@2@%%@CR:C6A00100047 @%%@AB@%10.5  Using Graphic Fonts%@AE@%%@EH@%%@NL@%
  11314. %@NL@%
  11315. A "font" is a collection of stylized text characters. Each font consists of
  11316. a typeface with several type sizes.%@CR:C6A00100048 @%  %@NL@%
  11317. %@NL@%
  11318. A "typeface" is the name of the displayed text─Courier, for example, or
  11319. Roman. The list on the next page shows six of the typefaces available with
  11320. the Microsoft C font library.  %@NL@%
  11321. %@NL@%
  11322. "Type size" measures the screen area occupied by individual characters in
  11323. units of screen pixels. For example, "Courier 12 x 9" denotes text of
  11324. Courier typeface, with each character occupying a screen area of 12 vertical
  11325. pixels by 9 horizontal pixels.  %@NL@%
  11326. %@NL@%
  11327. A font's spacing can be fixed or proportional. "Fixed" means that all
  11328. characters have the same width in pixels. "Proportional" means the width
  11329. varies. An %@AI@%i%@AE@%, for example, is thinner than an %@AI@%M%@AE@%.  %@NL@%
  11330. %@NL@%
  11331. The Microsoft C font functions use two methods to create fonts. The first
  11332. technique generates Courier, Helv, and Tms Rmn fonts through a "bit-mapping"
  11333. (or "raster-mapping") technique. Bit-mapping defines character images with
  11334. binary data. Each bit in the map corresponds to a screen pixel. If a bit is
  11335. 1, its associated pixel is set to the current screen color.  %@NL@%
  11336. %@NL@%
  11337. The second method creates the remaining three type styles─Modern, Script,
  11338. and Roman─as "vector-mapped" fonts. Vector-mapping represents each character
  11339. in terms of lines and arcs.  %@NL@%
  11340. %@NL@%
  11341. Each method has advantages and disadvantages. Bit-mapped characters are more
  11342. completely formed since the pixel mapping is predetermined. However, they
  11343. cannot be scaled. Vector-mapped text can be scaled to any size, but the
  11344. characters tend to lack the solid appearance of the bit-mapped characters.  %@NL@%
  11345. %@NL@%
  11346. The following list shows six sample typefaces:  %@NL@%
  11347. %@NL@%
  11348. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  11349. %@NL@%
  11350. Table 10.6 lists available sizes for each font. Note that the bit-mapped
  11351. fonts come in preset sizes as measured in pixels. The vector-mapped fonts
  11352. can be scaled to any size.  %@NL@%
  11353. %@NL@%
  11354. %@AB@%Table 10.6  %@AB@%Typefaces and Type Sizes in the C Library%@AE@%%@AE@%
  11355.  
  11356. %@TH:  21   759 02 10 09 18 39 @%
  11357. Typeface  Mapping  Size (in pixels)  Spacing
  11358. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11359. Courier   Bit      10 x 8, 12 x 9,   Fixed
  11360.                    15 x 12           
  11361.  
  11362. Helv      Bit      10 x 5, 12 x 7,   Proportional
  11363.                    15 x 8, 18 x 9,   
  11364.                    22 x 12, 28 x 16  
  11365.  
  11366. Tms Rmn   Bit      10 x 5, 12 x 6,   Proportional
  11367.                    15 x 8, 16 x 9,   
  11368.                    20 x 12, 26 x 16  
  11369.  
  11370. Modern    Vector   Scaled            Proportional
  11371.  
  11372. Script    Vector   Scaled            Proportional
  11373.  
  11374. Roman     Vector   Scaled            Proportional
  11375.  
  11376. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11377.  
  11378. %@TE:  21   759 02 10 09 18 39 @%
  11379.  
  11380. %@NL@%
  11381. %@3@%%@CR:C6A00100049 @%%@AB@%10.5.1  Using the C Font Library%@AE@%%@EH@%%@NL@%
  11382. %@NL@%
  11383. Data for both bit-mapped and vector-mapped fonts reside in .FON files. For
  11384. example, the files MODERN.FON, ROMAN.FON, and SCRIPT.FON hold data for the
  11385. three vector-mapped fonts.%@CR:C6A00100050 @%%@CR:C6A00100051 @%  %@NL@%
  11386. %@NL@%
  11387. %@AU@% You can use Microsoft Windows .FON files.%@AE@%  %@NL@%
  11388. %@NL@%
  11389. The Microsoft C .FON files are identical to the .FON files used in the
  11390. Microsoft Windows operating environment. If you have access to Windows, you
  11391. can use any of its .FON files with Microsoft C font functions. In addition,
  11392. several vendors offer software that creates or modifies .FON files, allowing
  11393. you to design your own fonts.  %@NL@%
  11394. %@NL@%
  11395. Your programs should follow these three steps to display fonted text:  %@NL@%
  11396. %@NL@%
  11397. %@NL@%
  11398.   1.  Register the fonts.%@NL@%
  11399. %@NL@%
  11400.   2.  Set the current font from the register.%@NL@%
  11401. %@NL@%
  11402.   3.  Display text using the current font.%@NL@%
  11403. %@NL@%
  11404. %@NL@%
  11405. The following sections describe each of the three steps in detail. An
  11406. example program in Section 10.5.5 demonstrates these steps.  %@NL@%
  11407. %@NL@%
  11408. %@NL@%
  11409. %@3@%%@CR:C6A00100052 @%%@AB@%10.5.2  Registering the Fonts%@AE@%%@EH@%%@NL@%
  11410. %@NL@%
  11411. The fonts must first be organized into a list in memory, a process called
  11412. "registering." Register fonts by calling the function %@AB@%_registerfonts%@AE@%. This
  11413. function reads header information from specified .FON files, building a list
  11414. of file information but not reading any mapping data from the files.%@CR:C6A00100053 @%%@CR:C6A00100054 @%  %@NL@%
  11415. %@NL@%
  11416. The GRAPH.H file prototypes the %@AB@%_registerfonts%@AE@% function as  %@NL@%
  11417. %@NL@%
  11418. %@AS@%  short far _registerfonts( unsigned char far * );%@AE@%%@NL@%
  11419. %@NL@%
  11420. The argument points to a string containing a file name. The file name is the
  11421. name of the .FON file for the desired font. The file name can include wild
  11422. cards, allowing you to register several fonts with one call to
  11423. %@AB@%_registerfonts%@AE@%.  %@NL@%
  11424. %@NL@%
  11425. If it successfully reads one or more .FON files, %@AB@%_registerfonts%@AE@% returns the
  11426. number of fonts. If the function fails, it returns a negative error code.  %@NL@%
  11427. %@NL@%
  11428. %@NL@%
  11429. %@3@%%@CR:C6A00100055 @%%@AB@%10.5.3  Setting the Current Font%@AE@%%@EH@%%@NL@%
  11430. %@NL@%
  11431. Call the function %@AB@%_setfont%@AE@% to select a current font. This function checks to
  11432. see if the requested font is registered, then reads the mapping data from
  11433. the appropriate .FON file. A font must be registered and marked current
  11434. before your program can display text in that font.  %@NL@%
  11435. %@NL@%
  11436. The GRAPH.H file prototypes the%@AB@%_setfonts%@AE@% function as  %@NL@%
  11437. %@NL@%
  11438. %@AS@%  short far _setfont( unsigned char far * );%@AE@%%@NL@%
  11439. %@NL@%
  11440. The function's argument is a pointer to a character string. The string
  11441. consists of letter codes that describe the desired font, as outlined here:  %@NL@%
  11442. %@NL@%
  11443. %@AB@%Option Code%@AE@%                       %@AB@%Meaning%@AE@%
  11444. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11445. %@AB@%b%@AE@%                                 The best fit from the registered fonts. 
  11446.                                   This option instructs %@AB@%_setfont%@AE@% to accept
  11447.                                   the closest-fitting font if a font of 
  11448.                                   the specified size is not registered.
  11449.  
  11450.                                   If at least one font is registered, the %@AB@%%@AE@%
  11451.                                   %@AB@%b%@AE@% option always sets a current font. If 
  11452.                                   you do not specify the %@AB@%b%@AE@% option and an 
  11453.                                   exact matching font is not registered, 
  11454.                                   the%@AB@%%@AE@%
  11455.                                   %@AB@%_setfont%@AE@% function will fail. In this 
  11456.                                   case, any existing current font remains 
  11457.                                   current. Refer to on-line help for a 
  11458.                                   description of error codes returned by%@AB@%%@AE@%
  11459.                                   %@AB@%_setfont%@AE@%.
  11460.  
  11461.                                   The %@AB@%_setfont%@AE@% function uses four criteria
  11462.                                   for selecting the best fit. In 
  11463.                                   descending order of precedence, the four
  11464.                                   criteria are pixel height, typeface, 
  11465.                                   pixel width, and spacing (fixed or 
  11466.                                   proportional). If you request a 
  11467.                                   vector-mapped font,%@AB@% _setfont%@AE@% sizes the 
  11468.                                   font to correspond with the specified 
  11469.                                   pixel height and width. If you request a
  11470.                                   raster-mapped (bit-mapped) font,%@AB@%%@AE@%
  11471.                                   %@AB@%_setfont%@AE@% chooses the closest available 
  11472.                                   size. If the requested type size for a 
  11473.                                   raster-mapped font fits exactly between 
  11474.                                   two registered fonts, the smaller size 
  11475.                                   takes precedence.
  11476.  
  11477. %@AB@%f%@AE@%                                 Fixed-spaced font.
  11478.  
  11479. %@AB@%h%@AE@%%@AI@%y%@AE@%                                Character height, where %@AI@%y%@AE@% is the height 
  11480.                                   in pixels.
  11481.  
  11482. %@AB@%n%@AE@%%@AI@%x%@AE@%                                Font number %@AI@%x%@AE@%, where %@AI@%x%@AE@% is less than or 
  11483.                                   equal to the value returned by %@AB@%%@AE@%
  11484.                                   %@AB@%_registerfonts%@AE@%. For example, the option %@AB@%%@AE@%
  11485.                                   %@AB@%n%@AE@%3 makes the third registered font 
  11486.                                   current, if three or more fonts are 
  11487.                                   registered.
  11488.  
  11489. %@AB@%p%@AE@%                                 Proportional-spaced font.
  11490.  
  11491. %@AB@%r%@AE@%                                 Raster-mapped (bit-mapped) font.
  11492.  
  11493. %@AB@%t`%@AE@%%@AI@%fontname%@AE@%%@AB@%'%@AE@%                       Typeface of the font in single quotes. 
  11494.                                   The %@AI@%fontname%@AE@% string is one of the 
  11495.                                   following:
  11496.  
  11497.   courier  modern  helv  script  tms rmn  roman
  11498.  
  11499.                                   Note the space in tms rmn. Additional 
  11500.                                   font files use other names for %@AI@%fontname%@AE@%.
  11501.                                   Refer to the vendor's documentation for 
  11502.                                   these names.
  11503.  
  11504. %@AB@%v%@AE@%                                 Vector-mapped font.
  11505.  
  11506. %@AB@%w%@AE@%%@AI@%x%@AE@%                                Character width, where %@AI@%x%@AE@% is the width in
  11507.                                   pixels.
  11508.  
  11509. Option codes are not case sensitive and can be listed in any order. You can
  11510. separate codes with spaces or any other character that is not a valid option
  11511. code. The %@AB@%_setfont%@AE@% function ignores all invalid codes.  %@NL@%
  11512. %@NL@%
  11513. The %@AB@%_setfont%@AE@% function updates a data area with parameters of the current
  11514. font. The data area is in the form of a structure, defined in GRAPH.H as
  11515. follows:  %@NL@%
  11516. %@NL@%
  11517. %@AS@%  struct _fontinfo
  11518. %@AS@%  {
  11519. %@AS@%     int     type;          /* set = vector,clear = bit map */
  11520. %@AS@%     int     ascent;        /* pix dist from top to base */
  11521. %@AS@%     int     pixwidth;      /* character width in pixels */
  11522. %@AS@%     int     pixheight;     /* character height in pixels */
  11523. %@AS@%     int     avgwidth;      /* average character width */
  11524. %@AS@%     char    filename[81];  /* file name including path */
  11525. %@AS@%     char    faceName[32];  /* font name */
  11526. %@AS@%  };%@AE@%%@NL@%
  11527. %@NL@%
  11528. If you want to retrieve the parameters of the current font, call the
  11529. function %@AB@%_getfontinfo%@AE@%.  %@NL@%
  11530. %@NL@%
  11531. %@NL@%
  11532. %@3@%%@CR:C6A00100056 @%%@AB@%10.5.4  Displaying Text%@AE@%%@EH@%%@NL@%
  11533. %@NL@%
  11534. The last step, displaying text, consists of two parts. First you must select
  11535. a screen position for the text with the graphics function %@AB@%_moveto%@AE@%. Then
  11536. display fonted text at that position with the function %@AB@%_outgtext%@AE@%. The
  11537. %@AB@%_moveto%@AE@% function takes pixel coordinates as arguments. The coordinates
  11538. locate the top left of the first character in the text string.  %@NL@%
  11539. %@NL@%
  11540. %@NL@%
  11541. %@3@%%@CR:C6A00100057 @%%@AB@%10.5.5  A Sample Program%@AE@%%@EH@%%@NL@%
  11542. %@NL@%
  11543. The program SAMPLER.C displays sample text in all the available fonts, then
  11544. exits when a key is pressed. Make sure the .FON files are in the current
  11545. directory before running the program.  %@NL@%
  11546. %@NL@%
  11547. %@AS@%  /* SAMPLER.C: Displays sample text in various fonts. */
  11548. %@AS@%  
  11549. %@AS@%  #include <stdio.h>
  11550. %@AS@%  #include <conio.h>
  11551. %@AS@%  #include <stdlib.h>
  11552. %@AS@%  #include <graph.h>
  11553. %@AS@%  #include <string.h>
  11554. %@AS@%  #define NFONTS 6
  11555. %@AS@%  
  11556. %@AS@%  main()
  11557. %@AS@%  
  11558. %@AS@%  {
  11559. %@AS@%     static unsigned char *text[2*NFONTS] =
  11560. %@AS@%     {
  11561. %@AS@%         "COURIER",        "courier",
  11562. %@AS@%         "HELV",           "helv",
  11563. %@AS@%         "TMS RMN",        "tms rmn",
  11564. %@AS@%         "MODERN",         "modern",
  11565. %@AS@%         "SCRIPT",         "script",
  11566. %@AS@%         "ROMAN",          "roman"
  11567. %@AS@%     };
  11568. %@AS@%     static unsigned char *face[NFONTS] =
  11569. %@AS@%     {
  11570. %@AS@%         "t'courier'",
  11571. %@AS@%         "t'helv'",
  11572. %@AS@%         "t'tms rmn'",
  11573. %@AS@%         "t'modern'",
  11574. %@AS@%         "t'script'",
  11575. %@AS@%         "t'roman'"
  11576. %@AS@%     };%@AE@%%@NL@%
  11577. %@NL@%
  11578. %@AS@%  static unsigned char list[20];
  11579. %@AS@%     struct videoconfig vc;
  11580. %@AS@%     int mode = _VRES16COLOR;
  11581. %@AS@%     register i;%@AE@%%@NL@%
  11582. %@NL@%
  11583. %@AS@%  /*   Read header info from all .FON files in
  11584. %@AS@%      *   current directory
  11585. %@AS@%      */
  11586. %@AS@%  
  11587. %@AS@%     if( _registerfonts( "*.FON" ) < 0 )
  11588. %@AS@%     {
  11589. %@AS@%        _outtext( "Error: can't register fonts" );
  11590. %@AS@%        exit( 0 );
  11591. %@AS@%     }
  11592. %@AS@%  
  11593. %@AS@%     /*   Set highest available video mode */
  11594. %@AS@%  
  11595. %@AS@%     if( _setvideomode( _MAXRESMODE ) == 0 )
  11596. %@AS@%        exit ( 0 );
  11597. %@AS@%  
  11598. %@AS@%     /*   Copy video configuration into structure vc */
  11599. %@AS@%  
  11600. %@AS@%     _getvideoconfig( &vc );
  11601. %@AS@%  
  11602. %@AS@%     /*   Display six lines of sample text */
  11603. %@AS@%  
  11604. %@AS@%     for( i = 0; i < NFONTS; i++ )
  11605. %@AS@%     {
  11606. %@AS@%        strcpy( list, face[i] );
  11607. %@AS@%        strcat( list, "h30w24b" );
  11608. %@AS@%  
  11609. %@AS@%        if( _setfont( list ) >= 0 )
  11610. %@AS@%        {
  11611. %@AS@%            _setcolor( i + 1 );
  11612. %@AS@%            _moveto( 0, (i * vc.numypixels) / NFONTS );
  11613. %@AS@%            _outgtext( text[i * 2] );
  11614. %@AS@%            _moveto( vc.numxpixels / 2,
  11615. %@AS@%                        (i * vc.numypixels) / NFONTS );
  11616. %@AS@%            _outgtext( text[(i * 2) + 1] );
  11617. %@AS@%        }
  11618. %@AS@%        else
  11619. %@AS@%        {
  11620. %@AS@%            _setvideomode( _DEFAULTMODE );
  11621. %@AS@%            _outtext( "Error: can't set font" );
  11622. %@AS@%            exit( 0 );
  11623. %@AS@%        }
  11624. %@AS@%     }%@AE@%%@NL@%
  11625. %@NL@%
  11626. %@AS@%  getch();
  11627. %@AS@%     _setvideomode( _DEFAULTMODE );
  11628. %@AS@%  
  11629. %@AS@%     /* Return memory when finished with fonts */
  11630. %@AS@%  
  11631. %@AS@%     _unregisterfonts();
  11632. %@AS@%     exit( 0 );
  11633. %@AS@%  }%@AE@%%@NL@%
  11634. %@NL@%
  11635. %@NL@%
  11636. %@3@%%@CR:C6A00100058 @%%@AB@%10.5.6  Using Fonts Effectively%@AE@%%@EH@%%@NL@%
  11637. %@NL@%
  11638. Displaying fonts is simply another form of graphics; using fonts effectively
  11639. requires little programming effort. Still, there are a few things to watch:%@CR:C6A00100059 @%%@CR:C6A00100060 @%
  11640. %@NL@%
  11641. %@NL@%
  11642. %@NL@%
  11643.   ■   Remember that the video mode should be set only once. If you generate
  11644.       an image with presentation graphics and want to add text to it, do not
  11645.       reset the video mode prior to calling the font routines. Doing so will
  11646.       blank the screen, destroying the original image.%@NL@%
  11647. %@NL@%
  11648.   ■   The %@AB@%_setfont%@AE@% function reads specified .FON files to obtain mapping
  11649.       data for the current font. Each call to %@AB@%_setfont%@AE@% causes a disk access
  11650.       and overwrites the old font data in memory. If you want to show text
  11651.       of different styles on the same screen, display all text of one font
  11652.       before moving on to the others. Minimizing the number of calls to
  11653.       %@AB@%_setfont%@AE@% saves time spent in disk I/O and memory reloads.  %@NL@%
  11654. %@NL@%
  11655.   ■   When your program finishes using the fonts library, you may want to
  11656.       free the memory occupied by the register list by calling
  11657.       %@AB@%_unregisterfonts%@AE@%. This function frees the memory allocated by
  11658.       %@AB@%_registerfonts%@AE@%. The register information for each type size of each
  11659.       font takes up approximately 140 bytes of memory. %@NL@%
  11660. %@NL@%
  11661.   ■   Aesthetic suggestions for the printed page also apply to screen text.
  11662.       Typefaces are more effective when they do not compete with each other
  11663.       for attention. Restricting the number of styles per screen to one or
  11664.       two generally results in a more pleasing, less cluttered image.%@NL@%
  11665. %@NL@%
  11666. %@NL@%
  11667.   %@NL@%
  11668. %@NL@%
  11669. %@NL@%
  11670. %@NL@%
  11671. %@NL@%
  11672. %@NL@%
  11673. %@NL@%
  11674. %@CR:C6A00110001 @%%@1@%%@AB@%Chapter 11  Creating Charts and Graphs%@AE@%%@EH@%%@NL@%
  11675. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11676. %@NL@%
  11677. The low-level graphics functions described in Chapter 10, "Communicating
  11678. with Graphics," draw points, lines, and shapes. Although it is possible to
  11679. use them to generate charts and graphs, an additional set of high-level
  11680. graphics functions is better suited to this task.  %@NL@%
  11681. %@NL@%
  11682. "Presentation graphics" is a set of high-level functions that displays
  11683. presentation-quality graphics. These functions transform numeric data into
  11684. pie charts, bar and column charts, line graphs, and scatter diagrams.  %@NL@%
  11685. %@NL@%
  11686. This chapter describes how to use presentation graphics.  %@NL@%
  11687. %@NL@%
  11688. %@NL@%
  11689. %@2@%%@CR:C6A00110002 @%%@AB@%11.1  Overview of Presentation Graphics%@AE@%%@EH@%%@NL@%
  11690. %@NL@%
  11691. The presentation graphics library PGCHART.LIB contains 22 functions. They
  11692. are listed in Table 11.1 for convenient reference.  %@NL@%
  11693. %@NL@%
  11694. %@AB@%Table 11.1  %@AB@%Presentation Graphics Function%@AE@%%@AE@%
  11695.  
  11696. %@TH:  11   968 02 20 22 34 @%
  11697. Primary Functions   Secondary Functions
  11698. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11699. %@AB@%_pg_chart%@AE@%           %@AB@%_pg_analyzechart%@AE@%      %@AB@%_pg_hlabelchart%@AE@%
  11700. %@AB@%_pg_chartms%@AE@%         %@AB@%_pg_analyzechartms%@AE@%    %@AB@%_pg_resetpalette%@AE@%
  11701. %@AB@%_pg_chartpie%@AE@%        %@AB@%_pg_analyzepie%@AE@%        %@AB@%_pg_resetstyleset%@AE@%
  11702. %@AB@%_pg_chartscatter%@AE@%    %@AB@%_pg_analyzescatter%@AE@%    %@AB@%_pg_setchardef%@AE@%
  11703. %@AB@%_pg_chartscatterms%@AE@%  %@AB@%_pg_analyzescatterms%@AE@%  %@AB@%_pg_setpalette%@AE@%
  11704. %@AB@%_pg_defaultchart%@AE@%    %@AB@%_pg_getchardef%@AE@%        %@AB@%_pg_setstyleset%@AE@%
  11705. %@AB@%_pg_initchart%@AE@%       %@AB@%_pg_getpalette%@AE@%        %@AB@%_pg_vlabelchart%@AE@%
  11706.                     %@AB@%_pg_getstyleset%@AE@%
  11707. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11708. %@TE:  11   968 02 20 22 34 @%
  11709.  
  11710. %@AU@% The seven primary functions initialize variables and display selected chart
  11711. %@AU@%types.%@AE@%  %@NL@%
  11712. %@NL@%
  11713. In most cases, you will be using only seven "primary functions." These
  11714. functions initialize variables and display selected chart types. The 15
  11715. "secondary functions" of presentation graphics do not directly display
  11716. charts. Most of them retrieve or set data in the presentation graphics chart
  11717. environment.  %@NL@%
  11718. %@NL@%
  11719. Among the secondary functions are the "analysis functions," identified by
  11720. the prefix %@AB@%_pg_analyze%@AE@%. These five functions calculate default values that
  11721. pertain to a given chart type and data set. Calling an analysis function has
  11722. the same effect as calling a corresponding primary function, except that the
  11723. chart is not displayed. This allows you to pass on to the library the burden
  11724. of calculating values. You can then make modifications to the resulting
  11725. values and call a primary routine to display the chart.  %@NL@%
  11726. %@NL@%
  11727. Use the %@AB@%_pg_hlabelchart%@AE@% and %@AB@%_pg_vlabelchart%@AE@% functions to display text that
  11728. is not part of a title or axis label on your chart. These functions enable
  11729. you to attach notes or other messages to your chart.  %@NL@%
  11730. %@NL@%
  11731. %@NL@%
  11732. %@2@%%@CR:C6A00110003 @%%@AB@%11.2  Parts of a Graph%@AE@%%@EH@%%@NL@%
  11733. %@NL@%
  11734. This section describes the terms used to refer to the different kinds of
  11735. information that can be plotted. The various types of charts and graphs are
  11736. also defined.  %@NL@%
  11737. %@NL@%
  11738. %@NL@%
  11739. %@4@%%@AB@%Data Series%@AE@%%@EH@%%@NL@%
  11740. %@NL@%
  11741. Data that are related by a common idea or purpose constitute a "series." For
  11742. example, the prices of a futures commodity over the course of a year form a
  11743. single series of data. The volume forms a second data series.  %@NL@%
  11744. %@NL@%
  11745. When you include several series in one chart, characteristics such as color
  11746. and pattern can help distinguish one from another. You can more readily
  11747. differentiate series on a color monitor than you can on a monochrome
  11748. monitor. The number of series that can appear on the same chart depends on
  11749. the chart type and the number of available colors.  %@NL@%
  11750. %@NL@%
  11751. %@NL@%
  11752. %@4@%%@AB@%Categories%@AE@%%@EH@%%@NL@%
  11753. %@NL@%
  11754. "Categories" are nonnumeric data. A set of categories forms a frame of
  11755. reference for the comparison of numeric data. For example, the months of the
  11756. year are categories against which numeric data such as inches of rainfall
  11757. can be plotted.  %@NL@%
  11758. %@NL@%
  11759. Regional sales provide another example. A chart can compare a company's
  11760. sales in different parts of the country. Each region forms a category.  %@NL@%
  11761. %@NL@%
  11762. %@NL@%
  11763. %@4@%%@AB@%Values%@AE@%%@EH@%%@NL@%
  11764. %@NL@%
  11765. "Values" are numeric data. Sales, stock prices, air temperatures, and
  11766. populations are all series of values that can be plotted against categories
  11767. or against other values.  %@NL@%
  11768. %@NL@%
  11769. Presentation graphics allows you to overlay different series of value data
  11770. on a single graph. For example, average monthly temperatures or monthly
  11771. sales of heating oil during different years─or a combination of temperatures
  11772. and sales─can be plotted together on the same graph.  %@NL@%
  11773. %@NL@%
  11774. %@NL@%
  11775. %@4@%%@AB@%Pie Charts%@AE@%%@EH@%%@NL@%
  11776. %@NL@%
  11777. "Pie charts" are used to represent data by showing the relationship of each
  11778. part to the whole. A good example is a company's annual budget. A pie chart
  11779. allows you to view each area of revenue or spending by its relative size
  11780. within the context of the entire company budget.  %@NL@%
  11781. %@NL@%
  11782. Presentation graphics can display either a standard or an "exploded" pie
  11783. chart. The exploded view shows the pie with one or more pieces separated for
  11784. emphasis. You can label each slice of a pie chart with a percentage figure
  11785. if you wish.  %@NL@%
  11786. %@NL@%
  11787. %@NL@%
  11788. %@4@%%@AB@%Bar and Column Charts%@AE@%%@EH@%%@NL@%
  11789. %@NL@%
  11790. As the name implies, a "bar chart" shows data as horizontal bars. Bar charts
  11791. show comparisons among items rather than absolute value.  %@NL@%
  11792. %@NL@%
  11793. "Column charts" are vertical bar charts. Column charts are frequently used
  11794. to show variations over a period of time, since they suggest time flow
  11795. better than a bar chart.  %@NL@%
  11796. %@NL@%
  11797. %@NL@%
  11798. %@4@%%@AB@%Line Graphs%@AE@%%@EH@%%@NL@%
  11799. %@NL@%
  11800. "Line graphs" illustrate trends or changes in data. They show how a series
  11801. of values varies against a particular category─for example, average
  11802. temperatures throughout one year.  %@NL@%
  11803. %@NL@%
  11804. Traditionally, line graphs show a collection of data points connected by
  11805. lines. Presentation graphics can also plot points that are not connected by
  11806. lines.  %@NL@%
  11807. %@NL@%
  11808. %@NL@%
  11809. %@4@%%@AB@%Scatter Diagrams%@AE@%%@EH@%%@NL@%
  11810. %@NL@%
  11811. A "scatter diagram" is the only type of graph available in presentation
  11812. graphics that directly compares values with values. A scatter diagram simply
  11813. plots points.  %@NL@%
  11814. %@NL@%
  11815. Scatter diagrams illustrate the relationship between numeric values in
  11816. different groups of data. They graphically show trends and correlations not
  11817. easily detected from rows and columns of raw numbers.  %@NL@%
  11818. %@NL@%
  11819. Scatter diagrams are most useful with large amounts of data. Consider, for
  11820. example, the relationship between personal income and family size. If you
  11821. poll one thousand wage earners for their income and family size, you have a
  11822. scatter diagram with one thousand points. If you combine your results so
  11823. that you are left with one average income for each family size, you have a
  11824. line graph.  %@NL@%
  11825. %@NL@%
  11826. %@NL@%
  11827. %@4@%%@AB@%Axes%@AE@%%@EH@%%@NL@%
  11828. %@NL@%
  11829. All presentation graphics charts except pie charts are displayed with two
  11830. perpendicular reference axes. The vertical, or %@AI@%y%@AE@%, axis runs from top to
  11831. bottom of the chart and is placed against the left side of the screen. The
  11832. horizontal, or %@AI@%x%@AE@%, axis runs from left to right across the bottom of the
  11833. screen.  %@NL@%
  11834. %@NL@%
  11835. %@AU@% The chart type determines the axis used for category data and the axis for
  11836. %@AU@%value data.%@AE@%  %@NL@%
  11837. %@NL@%
  11838. The %@AI@%x%@AE@% axis is the category axis for column and line charts and the value
  11839. axis for bar charts. The %@AI@%y%@AE@% axis is the value axis for column and line charts
  11840. and the category axis for bar charts.  %@NL@%
  11841. %@NL@%
  11842. %@NL@%
  11843. %@4@%%@AB@%Chart Windows%@AE@%%@EH@%%@NL@%
  11844. %@NL@%
  11845. The "chart window" defines that part of the screen on which the chart is
  11846. drawn. By default, the window fills the entire screen, but presentation
  11847. graphics allows you to resize the window for smaller graphs. By redefining
  11848. the chart window to different screen locations, you can view separate graphs
  11849. together on the same screen.  %@NL@%
  11850. %@NL@%
  11851. %@NL@%
  11852. %@4@%%@AB@%Data Windows%@AE@%%@EH@%%@NL@%
  11853. %@NL@%
  11854. While the chart window defines the entire graph including axes and labels,
  11855. the "data window" defines only the actual plotting area. This is the portion
  11856. of the graph to the right of the %@AI@%y%@AE@% axis and above the %@AI@%x%@AE@% axis. You cannot
  11857. specify or adjust the size of the data window. Presentation graphics
  11858. automatically determines its size based on the dimensions of the chart
  11859. window.  %@NL@%
  11860. %@NL@%
  11861. %@NL@%
  11862. %@4@%%@AB@%Chart Styles%@AE@%%@EH@%%@NL@%
  11863. %@NL@%
  11864. Each of the five types of presentation graphics charts can appear in two
  11865. different "chart styles," as described in Table 11.2.  %@NL@%
  11866. %@NL@%
  11867. %@AB@%Table 11.2  %@AB@%Presentation Graphics Chart Styles%@AE@%%@AE@%
  11868.  
  11869. %@TH:   8   488 02 12 20 44 @%
  11870. Chart Type  Chart Style #1      Chart Style #2
  11871. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11872. Pie         With percentages    Without percentages
  11873. Bar         Side-by-side        Stacked
  11874. Column      Side-by-side        Stacked
  11875. Line        Points with lines   Points only
  11876. Scatter     Points with lines   Points only
  11877. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11878. %@TE:   8   488 02 12 20 44 @%
  11879.  
  11880. Bar and column charts have only one style when displaying a single series of
  11881. data. The styles "side-by-side" and "stacked" are applicable when more than
  11882. one series appears on the same chart. The first style arranges the bars or
  11883. columns for the different series side by side, showing relative heights or
  11884. lengths. The stacked style, illustrated for a column chart in Figure 11.3,
  11885. emphasizes relative sizes between bars or columns.  %@NL@%
  11886. %@NL@%
  11887. %@NL@%
  11888. %@4@%%@AB@%Legends%@AE@%%@EH@%%@NL@%
  11889. %@NL@%
  11890. %@AU@% Legends help identify  individual data series.%@AE@%  %@NL@%
  11891. %@NL@%
  11892. When displaying more than one data series on a chart, presentation graphics
  11893. uses different colors, line styles, or patterns to differentiate them.
  11894. Presentation graphics also can display a "legend" that labels the different
  11895. series of a chart. For a pie chart, the legend labels individual slices of
  11896. the pie.  %@NL@%
  11897. %@NL@%
  11898. A sample of the color and pattern used to graph the series appears next to
  11899. the series label. This identifies the set of data to which the labels
  11900. belong.  %@NL@%
  11901. %@NL@%
  11902. You may change the font displayed by calling the %@AB@%_registerfonts%@AE@% and %@AB@%_setfont%@AE@%
  11903. functions (see Section 10.5 for more information about using fonts). If you
  11904. don't select a font, presentation graphics defaults to an internal font.  %@NL@%
  11905. %@NL@%
  11906. %@NL@%
  11907. %@2@%%@CR:C6A00110004 @%%@AB@%11.3  Writing a Presentation Graphics Program%@AE@%%@EH@%%@NL@%
  11908. %@NL@%
  11909. To write a C program that uses presentation graphics, follow these steps:  %@NL@%
  11910. %@NL@%
  11911. %@NL@%
  11912.   1.  Include the required header files, GRAPH.H and PGCHART.H, as well as
  11913.       any other header files your program may need.%@NL@%
  11914. %@NL@%
  11915.   2.  Set the video mode to a graphics mode. See Chapter 10, "Communicating
  11916.       with Graphics," for a description of video modes.%@NL@%
  11917. %@NL@%
  11918.   3.  Initialize the presentation graphics chart environment. Presentation
  11919.       graphics places charting parameters in data structures. The amount of
  11920.       initialization that must be done by your program depends on how
  11921.       extensively it relies on the defaults.%@NL@%
  11922. %@NL@%
  11923.   4.  Assemble the plot data. Data can be collected in a variety of ways: by
  11924.       calculating it elsewhere in the program, reading it from files, or
  11925.       entering it from the keyboard. All plot data must be assembled in
  11926.       arrays because the presentation graphics functions locate them through
  11927.       pointers.%@NL@%
  11928. %@NL@%
  11929.   5.  Call presentation graphics functions to display the chart. Pause while
  11930.       the chart is on the screen.%@NL@%
  11931. %@NL@%
  11932.   6.  Reset the video mode. When your program detects the signal to
  11933.       continue, it should reset the video to its original (default) mode.%@NL@%
  11934. %@NL@%
  11935. %@NL@%
  11936. After compiling the program, link it to the library modules PGCHART.LIB and
  11937. GRAPHICS.LIB.  %@NL@%
  11938. %@NL@%
  11939. The sample programs in Sections 11.3.1-11.3.3 use 5 of the 22 presentation
  11940. graphics functions: %@AB@%_pg_initchart%@AE@%, %@AB@%_pg_defaultchart%@AE@%, %@AB@%_pg_chartpie%@AE@%,
  11941. %@AB@%_pg_chart%@AE@%, and %@AB@%_pg_chartscatter%@AE@%. Each program is commented so that you can
  11942. recognize the steps given in this section.  %@NL@%
  11943. %@NL@%
  11944. %@NL@%
  11945. %@3@%%@CR:C6A00110005 @%%@AB@%11.3.1  Pie Chart%@AE@%%@EH@%%@NL@%
  11946. %@NL@%
  11947. The following program uses presentation graphics to display a pie chart for
  11948. monthly sales of orange juice over a year. The chart, which is shown in
  11949. Figure 11.1, remains on the screen until a key is pressed.  %@NL@%
  11950. %@NL@%
  11951. %@AS@%  /* PIE.C:  Create sample pie chart.  */
  11952. %@AS@%  
  11953. %@AS@%  #include <conio.h>
  11954. %@AS@%  #include <string.h>
  11955. %@AS@%  #include <graph.h>
  11956. %@AS@%  #include <pgchart.h>
  11957. %@AS@%  
  11958. %@AS@%  #define MONTHS 12
  11959. %@AS@%  
  11960. %@AS@%  typedef enum {FALSE, TRUE} boolean;
  11961. %@AS@%  
  11962. %@AS@%  float far value[MONTHS] = 
  11963. %@AS@%  {
  11964. %@AS@%      33.0, 27.0, 42.0, 64.0,106.0,157.0,
  11965. %@AS@%     182.0,217.0,128.0, 62.0, 43.0, 36.0
  11966. %@AS@%  };
  11967. %@AS@%  char far *category[MONTHS] = 
  11968. %@AS@%  {
  11969. %@AS@%     "Jan", "Feb", "Mar", "Apr",
  11970. %@AS@%     "May", "Jun", "Jly", "Aug",
  11971. %@AS@%     "Sep", "Oct", "Nov", "Dec"
  11972. %@AS@%  };
  11973. %@AS@%  short far explode[MONTHS] = {0};%@AE@%%@NL@%
  11974. %@NL@%
  11975. %@AS@%  main()
  11976. %@AS@%  {
  11977. %@AS@%     chartenv env;
  11978. %@AS@%     int mode = _VRES16COLOR;%@AE@%%@NL@%
  11979. %@NL@%
  11980. %@AS@%  /* Set highest video mode available */
  11981. %@AS@%  
  11982. %@AS@%     if( _setvideomode( _MAXRESMODE ) == 0 )
  11983. %@AS@%        exit( 0 );
  11984. %@AS@%  
  11985. %@AS@%     /* Initialize chart library and a default pie chart */
  11986. %@AS@%  
  11987. %@AS@%     _pg_initchart();
  11988. %@AS@%     _pg_defaultchart( &env, _PG_PIECHART, _PG_PERCENT );
  11989. %@AS@%  
  11990. %@AS@%     /* Add titles and some chart options */
  11991. %@AS@%  
  11992. %@AS@%     strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  11993. %@AS@%     env.maintitle.titlecolor = 6;
  11994. %@AS@%     env.maintitle.justify = _PG_RIGHT;
  11995. %@AS@%     strcpy( env.subtitle.title, "Orange Juice Sales" ); 
  11996. %@AS@%     env.subtitle.titlecolor = 6;
  11997. %@AS@%     env.subtitle.justify = _PG_RIGHT;
  11998. %@AS@%     env.chartwindow.border = FALSE;
  11999. %@AS@%  
  12000. %@AS@%     /* Parameters for call to _pg_chartpie are:
  12001. %@AS@%      *  
  12002. %@AS@%      *    env        - Environment variable
  12003. %@AS@%      *    category   - Category labels
  12004. %@AS@%      *    value      - Data to chart
  12005. %@AS@%      *    explode    - Separated pieces
  12006. %@AS@%      *    MONTHS     - Number of data values
  12007. %@AS@%      */
  12008. %@AS@%     if( _pg_chartpie( &env, category, value,
  12009. %@AS@%                       explode, MONTHS ) )
  12010. %@AS@%     {
  12011. %@AS@%        _setvideomode( _DEFAULTMODE );
  12012. %@AS@%        _outtext( "Error:  can't draw chart" );
  12013. %@AS@%     }
  12014. %@AS@%     else
  12015. %@AS@%     {
  12016. %@AS@%        getch(); 
  12017. %@AS@%        _setvideomode( _DEFAULTMODE );
  12018. %@AS@%     }
  12019. %@AS@%     return( 0 );
  12020. %@AS@%  }%@AE@%%@NL@%
  12021. %@NL@%
  12022. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12023. %@NL@%
  12024. %@NL@%
  12025. %@3@%%@CR:C6A00110006 @%%@AB@%11.3.2  Bar, Column, and Line Charts%@AE@%%@EH@%%@NL@%
  12026. %@NL@%
  12027. The code for the PIE.C program needs only minor alterations to produce bar,
  12028. column, and line charts for the same data:  %@NL@%
  12029. %@NL@%
  12030. %@NL@%
  12031.   ■   Replace the call to %@AB@%_pg_chartpie%@AE@% with %@AB@%_pg_chart%@AE@%. This function
  12032.       produces bar, column, and line charts depending on the value of the
  12033.       second argument for %@AB@%_pg_defaultchart%@AE@%.%@NL@%
  12034. %@NL@%
  12035.   ■   Give new arguments to %@AB@%_pg_defaultchart%@AE@% that specify chart type and
  12036.       style.%@NL@%
  12037. %@NL@%
  12038.   ■   Assign titles for the %@AI@%x%@AE@% axis and %@AI@%y%@AE@% axis in the structure %@AS@% env%@AE@%.%@NL@%
  12039. %@NL@%
  12040.   ■   Remove references to array %@AS@% explode%@AE@%, which is applicable only to pie
  12041.       charts. %@AS@% %@AE@%%@NL@%
  12042. %@NL@%
  12043. %@NL@%
  12044. The following example produces a bar chart for the store owner's data. The
  12045. result is shown in Figure 11.2.  %@NL@%
  12046. %@NL@%
  12047. %@AS@%  /* BAR.C:  Create sample bar chart. */
  12048. %@AS@%  
  12049. %@AS@%  #include <conio.h>
  12050. %@AS@%  #include <string.h>
  12051. %@AS@%  #include <graph.h>
  12052. %@AS@%  #include <pgchart.h>
  12053. %@AS@%  
  12054. %@AS@%  #define MONTHS 12
  12055. %@AS@%  
  12056. %@AS@%  typedef enum {FALSE, TRUE} boolean;
  12057. %@AS@%  
  12058. %@AS@%  float far value[MONTHS] = 
  12059. %@AS@%  { 
  12060. %@AS@%      33.0, 27.0, 42.0, 64.0,106.0,157.0,
  12061. %@AS@%     182.0,217.0,128.0, 62.0, 43.0, 36.0
  12062. %@AS@%  };
  12063. %@AS@%  char far *category[MONTHS] =
  12064. %@AS@%  {
  12065. %@AS@%     "Jan", "Feb", "Mar", "Apr",
  12066. %@AS@%     "May", "Jun", "Jly", "Aug",
  12067. %@AS@%     "Sep", "Oct", "Nov", "Dec"
  12068. %@AS@%  };
  12069. %@AS@%  
  12070. %@AS@%  main()
  12071. %@AS@%  {
  12072. %@AS@%     chartenv env;
  12073. %@AS@%     int mode = _VRES16COLOR;
  12074. %@AS@%  
  12075. %@AS@%     /* Set highest video mode available */
  12076. %@AS@%  
  12077. %@AS@%     if( _setvideomode( _MAXRESMODE ) == 0 )
  12078. %@AS@%        exit( 0 );
  12079. %@AS@%  
  12080. %@AS@%     /* Initialize chart library and a default bar chart */ 
  12081. %@AS@%     _pg_initchart();
  12082. %@AS@%     _pg_defaultchart( &env, _PG_BARCHART, _PG_PLAINBARS );
  12083. %@AS@%  
  12084. %@AS@%     /* Add titles and some chart options */
  12085. %@AS@%  
  12086. %@AS@%     strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  12087. %@AS@%     env.maintitle.titlecolor = 6;
  12088. %@AS@%     env.maintitle.justify = _PG_RIGHT;
  12089. %@AS@%     strcpy( env.subtitle.title, "Orange Juice Sales" );
  12090. %@AS@%     env.subtitle.titlecolor = 6;
  12091. %@AS@%     env.subtitle.justify = _PG_RIGHT;
  12092. %@AS@%     strcpy( env.yaxis.axistitle.title, "Months" );
  12093. %@AS@%     strcpy( env.xaxis.axistitle.title, "Quantity (cases)" );
  12094. %@AS@%     env.chartwindow.border = FALSE;%@AE@%%@NL@%
  12095. %@NL@%
  12096. %@AS@%  /* Parameters for call to _pg_chart are:
  12097. %@AS@%      *    env        - Environment variable
  12098. %@AS@%      *    category   - Category labels
  12099. %@AS@%      *    value      - Data to chart
  12100. %@AS@%      *    MONTHS     - Number of data values
  12101. %@AS@%      */
  12102. %@AS@%     if( _pg_chart( &env, category, value, MONTHS ) )
  12103. %@AS@%     {
  12104. %@AS@%        _setvideomode( _DEFAULTMODE );
  12105. %@AS@%        _outtext( "Error:  can't draw chart" );
  12106. %@AS@%     }
  12107. %@AS@%     else
  12108. %@AS@%     {
  12109. %@AS@%        getch(); 
  12110. %@AS@%        _setvideomode( _DEFAULTMODE );
  12111. %@AS@%     }
  12112. %@AS@%     return( 0 );
  12113. %@AS@%  }%@AE@%%@NL@%
  12114. %@NL@%
  12115. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12116. %@NL@%
  12117. The grocer's bar chart becomes a column chart in two easy steps. Simply
  12118. specify the new chart type when calling %@AB@%_pg_defaultchart%@AE@% and change the axis
  12119. titles. To produce a column chart for the grocer's data, replace the call to
  12120. %@AB@%_pg_defaultchart%@AE@% with  %@NL@%
  12121. %@NL@%
  12122. %@AS@%  _pg_defaultchart( &env, _PG_COLUMNCHART, _PG_PLAINBARS );%@AE@%%@NL@%
  12123. %@NL@%
  12124. Replace the last two calls to %@AB@%strcpy%@AE@% with  %@NL@%
  12125. %@NL@%
  12126. %@AS@%  strcpy( env.xaxis.axistitle.title, "Months" );
  12127. %@AS@%  strcpy( env.yaxis.axistitle.title, "Quantity (cases)" );%@AE@%%@NL@%
  12128. %@NL@%
  12129. Note that now the %@AI@%x%@AE@% axis is labeled "Months" and the %@AI@%y %@AE@%axis is labeled
  12130. "Quantity (cases)." Figure 11.3 shows the resulting column chart.  %@NL@%
  12131. %@NL@%
  12132. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12133. %@NL@%
  12134. Creating an equivalent line chart requires only one change. Use the same
  12135. code as for the column chart and replace the call to %@AB@%_pg_defaultchart%@AE@% with  %@NL@%
  12136. %@NL@%
  12137. %@AS@%  _pg_defaultchart( &env, _PG_LINECHART, _PG_POINTANDLINE );%@AE@%%@NL@%
  12138. %@NL@%
  12139. Figure 11.4 shows the line chart for the grocer's data.%@NL@%
  12140. %@NL@%
  12141. %@AU@%(Please refer to the printed book.)%@AE@%%@NL@%
  12142. %@NL@%
  12143. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12144. %@NL@%
  12145. %@NL@%
  12146. %@3@%%@CR:C6A00110007 @%%@AB@%11.3.3  Scatter Diagram%@AE@%%@EH@%%@NL@%
  12147. %@NL@%
  12148. The program SCATTER.C displays a scatter diagram that illustrates the
  12149. relationship between the sales of orange juice and hot chocolate throughout
  12150. a 12-month period. Figure 11.5 shows the results of SCATTER.C. Notice that
  12151. the scatter points form a slightly curved line, indicating that a
  12152. correlation exists between the sales of the two products. The demand for
  12153. orange juice is roughly inverse to the demand for hot chocolate.  %@NL@%
  12154. %@NL@%
  12155. %@AS@%  /* SCATTER.C:  Create sample scatter diagram. */
  12156. %@AS@%  
  12157. %@AS@%  #include <conio.h>
  12158. %@AS@%  #include <string.h>
  12159. %@AS@%  #include <graph.h>
  12160. %@AS@%  #include <pgchart.h>
  12161. %@AS@%  
  12162. %@AS@%  #define MONTHS 12
  12163. %@AS@%  
  12164. %@AS@%  typedef enum {FALSE, TRUE} boolean;%@AE@%%@NL@%
  12165. %@NL@%
  12166. %@AS@%  /* Orange juice sales */
  12167. %@AS@%  
  12168. %@AS@%  float far xvalue[MONTHS] = 
  12169. %@AS@%  { 
  12170. %@AS@%      33.0, 27.0, 42.0, 64.0,106.0,157.0,
  12171. %@AS@%     182.0,217.0,128.0, 62.0, 43.0, 36.0
  12172. %@AS@%  };
  12173. %@AS@%  
  12174. %@AS@%  /* Hot chocolate sales */
  12175. %@AS@%  
  12176. %@AS@%  float far yvalue[MONTHS] = 
  12177. %@AS@%  { 
  12178. %@AS@%     37.0, 37.0, 30.0, 19.0, 10.0,  5.0,
  12179. %@AS@%      2.0,  1.0,  7.0, 15.0, 28.0, 39.0
  12180. %@AS@%  };
  12181. %@AS@%  
  12182. %@AS@%  main()
  12183. %@AS@%  {
  12184. %@AS@%     chartenv env;
  12185. %@AS@%     int mode = _VRES16COLOR;
  12186. %@AS@%  
  12187. %@AS@%     /* Set highest video mode available */
  12188. %@AS@%  
  12189. %@AS@%     if( _setvideomode( _MAXRESMODE ) == 0 )
  12190. %@AS@%        exit( 0 );
  12191. %@AS@%     /* Initialize chart library and default
  12192. %@AS@%      * scatter diagram
  12193. %@AS@%      */
  12194. %@AS@%     _pg_initchart();
  12195. %@AS@%     _pg_defaultchart( &env, _PG_SCATTERCHART,
  12196. %@AS@%                       _PG_POINTONLY );
  12197. %@AS@%  
  12198. %@AS@%     /* Add titles and some chart options */
  12199. %@AS@%  
  12200. %@AS@%     strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  12201. %@AS@%     env.maintitle.titlecolor = 6;
  12202. %@AS@%     env.maintitle.justify = _PG_RIGHT;
  12203. %@AS@%     strcpy( env.subtitle.title,
  12204. %@AS@%             "Orange Juice vs Hot Chocolate" );
  12205. %@AS@%     env.subtitle.titlecolor = 6;
  12206. %@AS@%     env.subtitle.justify = _PG_RIGHT;
  12207. %@AS@%     env.yaxis.grid = TRUE;
  12208. %@AS@%     strcpy( env.xaxis.axistitle.title,
  12209. %@AS@%             "Orange Juice Sales" );
  12210. %@AS@%     strcpy( env.yaxis.axistitle.title,
  12211. %@AS@%             "Hot Chocolate Sales" );
  12212. %@AS@%     env.chartwindow.border = FALSE;%@AE@%%@NL@%
  12213. %@NL@%
  12214. %@AS@%  /* Parameters for call to _pg_chartscatter are:
  12215. %@AS@%      *    env        - Environment variable
  12216. %@AS@%      *    xvalue     - X-axis data
  12217. %@AS@%      *    yvalue     - Y-axis data
  12218. %@AS@%      *    MONTHS     - Number of data values
  12219. %@AS@%      */
  12220. %@AS@%     if( _pg_chartscatter( &env, xvalue,
  12221. %@AS@%                           yvalue, MONTHS ) )
  12222. %@AS@%     {
  12223. %@AS@%        _setvideomode( _DEFAULTMODE );
  12224. %@AS@%        _outtext( "Error:  can't draw chart" );
  12225. %@AS@%     }
  12226. %@AS@%     else
  12227. %@AS@%     {
  12228. %@AS@%        getch(); 
  12229. %@AS@%        _setvideomode( _DEFAULTMODE );
  12230. %@AS@%     }
  12231. %@AS@%     return( 0 );
  12232. %@AS@%  } %@AE@%%@NL@%
  12233. %@NL@%
  12234. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12235. %@NL@%
  12236. %@NL@%
  12237. %@2@%%@CR:C6A00110008 @%%@AB@%11.4  Manipulating Colors and Patterns%@AE@%%@EH@%%@NL@%
  12238. %@NL@%
  12239. Presentation graphics displays each data series in a way that makes it
  12240. discernible from other series. It does this by defining a separate "palette"
  12241. for every data series in a chart. Palettes consist of entries that determine
  12242. color, line style, fill pattern, and point character used to graph the
  12243. series.  %@NL@%
  12244. %@NL@%
  12245. Presentation graphics maintains its palettes as an array of structures. The
  12246. header file PGCHART.H defines the palette structures as shown below:  %@NL@%
  12247. %@NL@%
  12248. %@AS@%  /* Typedef for pattern bitmap */
  12249. %@AS@%  typedef unsigned char fillmap[8];
  12250. %@AS@%  
  12251. %@AS@%  /* Typedef for palette entry definition */
  12252. %@AS@%  typedef struct 
  12253. %@AS@%  {
  12254. %@AS@%     unsigned short color;
  12255. %@AS@%     unsigned short style;
  12256. %@AS@%     fillmap        fill;
  12257. %@AS@%     char           plotchar;
  12258. %@AS@%  } paletteentry;
  12259. %@AS@%  
  12260. %@AS@%  /* Typedef for palette definition */
  12261. %@AS@%  typedef paletteentry palettetype[_PG_PALETTELEN];%@AE@%%@NL@%
  12262. %@NL@%
  12263. Do not confuse the presentation graphics palettes with the adapter display
  12264. palettes, which are register values kept by the video controller. The
  12265. function %@AB@%_selectpalette%@AE@% described in Chapter 10, "Communicating with
  12266. Graphics," sets the display palette. It does not define the data series
  12267. palettes used by presentation graphics.  %@NL@%
  12268. %@NL@%
  12269. %@NL@%
  12270. %@3@%%@CR:C6A00110009 @%%@AB@%11.4.1  Color Pool%@AE@%%@EH@%%@NL@%
  12271. %@NL@%
  12272. %@AU@% The color pool determines the  colors of graphic elements (axes, labels,
  12273. %@AU@%legends, titles).%@AE@%  %@NL@%
  12274. %@NL@%
  12275. Presentation graphics organizes all chart colors into a "color pool." The
  12276. color pool holds the color index values valid for the current graphics mode.
  12277. (Refer to Chapter 10, "Communicating with Graphics," for more information
  12278. about the color index.) Palette structures contain color codes that refer to
  12279. the color pool. A palette's color index determines the colors used to graph
  12280. the data series associated with the palette. The colors of labels, titles,
  12281. legends, and axes are determined by the contents of the color pool.  %@NL@%
  12282. %@NL@%
  12283. The first element of the color pool is always 0, which is the color index
  12284. for the screen background color. The second element is always the highest
  12285. color index available for the graphics mode. The remaining elements repeat
  12286. the sequences of available pixel values, beginning with 1.  %@NL@%
  12287. %@NL@%
  12288. As shown in the example in Section 11.4, the first member of a palette data
  12289. structure is  %@NL@%
  12290. %@NL@%
  12291. %@AS@%  unsigned short color;%@AE@%%@NL@%
  12292. %@NL@%
  12293. This member defines the color index for the data series associated with the
  12294. palette.  %@NL@%
  12295. %@NL@%
  12296. An example should make this clearer. A graphics mode of %@AB@%_MRES4COLOR%@AE@% (320 by
  12297. 200 pixels) provides four colors for display. Color index values from 0 to 3
  12298. determine the possible colors─say, black, green, red, and brown,
  12299. respectively. The first eight elements of this color pool are shown below.  %@NL@%
  12300. %@NL@%
  12301. %@TH:  11   550 02 18 13 45 @%
  12302. Color Pool Index  Color Index  Color
  12303. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12304. 0                 0            Black
  12305. 1                 3            Brown
  12306. 2                 1            Green
  12307. 3                 2            Red
  12308. 4                 3            Brown
  12309. 5                 1            Green
  12310. 6                 2            Red
  12311. 7                 3            Brown
  12312. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12313. %@TE:  11   550 02 18 13 45 @%
  12314.  
  12315. Notice that the sequence of available foreground colors repeats from the
  12316. third element. The first data series in this case would be plotted in brown,
  12317. the second series in green, the third series in red, the fourth series again
  12318. in brown, and so forth.  %@NL@%
  12319. %@NL@%
  12320. Video adapters such as the EGA or the Hercules(R) InColor(tm) Card allow 16
  12321. on-screen colors. This allows presentation graphics to graph more series
  12322. without duplicating colors.  %@NL@%
  12323. %@NL@%
  12324. %@NL@%
  12325. %@3@%%@CR:C6A00110010 @%%@AB@%11.4.2  Style Pool%@AE@%%@EH@%%@NL@%
  12326. %@NL@%
  12327. Presentation graphics matches the color pool with a collection of different
  12328. line styles called the "style pool." Entries in the style pool define the
  12329. appearance of lines such as axes and grids. Lines can be solid, dotted,
  12330. dashed, or some combination of styles.  %@NL@%
  12331. %@NL@%
  12332. The second member of a palette structure defines a style code as  %@NL@%
  12333. %@NL@%
  12334. %@AS@%  unsigned short style;%@AE@%%@NL@%
  12335. %@NL@%
  12336. Each palette contains a style code that refers to an entry in the style pool
  12337. in the same way that it contains a color code that refers to an entry in the
  12338. color pool. The style code value in a palette is applicable only to line
  12339. graphs and lined scatter diagrams. The style code determines the appearance
  12340. of the lines drawn between points.  %@NL@%
  12341. %@NL@%
  12342. %@AU@% Use the different line styles in the style pool to differentiate series.%@AE@%  %@NL@%
  12343. %@NL@%
  12344. The palette's style code adds further variety to the lines of a multiseries
  12345. graph. It is most useful when the number of lines in a chart exceeds the
  12346. number of available colors. For example, a graph of nine different data
  12347. series must repeat colors if only three foreground colors are available for
  12348. the display. However, the style code for each color repetition will be
  12349. different, ensuring that none of the lines looks the same.  %@NL@%
  12350. %@NL@%
  12351. %@NL@%
  12352. %@3@%%@CR:C6A00110011 @%%@AB@%11.4.3  Pattern Pool%@AE@%%@EH@%%@NL@%
  12353. %@NL@%
  12354. Presentation graphics also maintains a pool of "fill patterns" that
  12355. determine the fill design for column, bar, and pie charts. The third member
  12356. of the palette structure holds the fill pattern. The pattern member is an
  12357. array:%@CR:C6A00110012 @%  %@NL@%
  12358. %@NL@%
  12359. %@AS@%  fillmap fill;%@AE@%%@NL@%
  12360. %@NL@%
  12361. where %@AS@% fillmap %@AE@% is type-defined as  %@NL@%
  12362. %@NL@%
  12363. %@AS@%  typedef unsigned char fillmap[8];%@AE@%%@NL@%
  12364. %@NL@%
  12365. Each fill pattern array holds an 8-by-8 bit map that defines the fill
  12366. pattern for the data series associated with the palette. Table 11.3 shows
  12367. how a fill pattern of diagonal stripes is created with the %@AS@% fill %@AE@% pattern
  12368. array.  %@NL@%
  12369. %@NL@%
  12370. The bit map in Table 11.3 corresponds to screen pixels. Each of the eight
  12371. layers of the map is a binary number, where a solid circle signifies 1 and
  12372. an open circle signifies 0. Thus the first layer of the map─that is, the
  12373. first byte─represents the binary number 10011001, which is the decimal
  12374. number 153.  %@NL@%
  12375. %@NL@%
  12376. %@AB@%Table   %@AB@%11.3 Fill Patterns%@AE@%%@AE@%
  12377.  
  12378. %@TH:  11   766 02 36 40 @%
  12379. Bit Map                             Value in Fill
  12380. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12381.   ∙  ∙      ∙  ∙                %@AS@%fill[0]%@AE@% = 153
  12382.     ∙  ∙      ∙  ∙              %@AS@%fill[1]%@AE@% = 204
  12383. ∙      ∙  ∙      ∙              %@AS@%fill[2]%@AE@% = 102
  12384. ∙  ∙      ∙  ∙                  %@AS@%fill[3]%@AE@% =   51
  12385.   ∙  ∙      ∙  ∙                %@AS@%fill[4]%@AE@% = 153
  12386.     ∙  ∙      ∙  ∙              %@AS@%fill[5]%@AE@% = 204
  12387. ∙      ∙  ∙      ∙              %@AS@%fill[6]%@AE@% = 102
  12388. ∙  ∙      ∙  ∙                  %@AS@%fill[7]%@AE@% =   51
  12389. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12390. %@TE:  11   766 02 36 40 @%
  12391.  
  12392. For example, if you want to create the pattern in Table 11.3 for your
  12393. chart's first data series, you must reset the %@AS@% fill%@AE@%%@AB@% %@AE@%array for the first
  12394. palette structure. You can do this in five steps:%@CR:C6A00110013 @%  %@NL@%
  12395. %@NL@%
  12396. %@NL@%
  12397.   1.  Declare a structure of type %@AB@%palettetype%@AE@% to hold the palette
  12398.       parameters.%@NL@%
  12399. %@NL@%
  12400.   2.  Call %@AB@%_pg_initchart%@AE@% to initialize the palettes with default values.%@NL@%
  12401. %@NL@%
  12402.   3.  Call the presentation graphics function %@AB@%_pg_getpalette%@AE@% to retrieve a
  12403.       copy of the current palette data.%@NL@%
  12404. %@NL@%
  12405.   4.  Assign the values given in Table 11.3 to the array %@AS@% fill %@AE@% for the
  12406.       first palette.%@NL@%
  12407. %@NL@%
  12408.   5.  Call the presentation graphics function %@AB@%_pg_setpalette%@AE@% to load the
  12409.       modified palette values.%@NL@%
  12410. %@NL@%
  12411. %@NL@%
  12412. The following lines of code demonstrate these five steps:  %@NL@%
  12413. %@NL@%
  12414. %@AS@%  /* Declare a structure array for palette data. */
  12415. %@AS@%  
  12416. %@AS@%  palettetype palette_struct;
  12417. %@AS@%  .
  12418. %@AS@%  .
  12419. %@AS@%  .
  12420. %@AS@%  /* Initialize chart library */
  12421. %@AS@%  
  12422. %@AS@%  _pg_initchart();
  12423. %@AS@%  .
  12424. %@AS@%  .
  12425. %@AS@%  .
  12426. %@AS@%  /* Copy current palette data into palette_struct */
  12427. %@AS@%  
  12428. %@AS@%  _pg_getpalette( palette_struct );
  12429. %@AS@%  
  12430. %@AS@%  /* Reinitialize fill pattern for first palette using
  12431. %@AS@%     values in Table .3 */
  12432. %@AS@%  
  12433. %@AS@%  palette_struct[1].fill[0] = 153;
  12434. %@AS@%  palette_struct[1].fill[1] = 204;
  12435. %@AS@%  palette_struct[1].fill[2] = 102;
  12436. %@AS@%  palette_struct[1].fill[3] =  51;
  12437. %@AS@%  palette_struct[1].fill[4] = 153;
  12438. %@AS@%  palette_struct[1].fill[5] = 204;
  12439. %@AS@%  palette_struct[1].fill[6] = 102;
  12440. %@AS@%  palette_struct[1].fill[7] =  51;
  12441. %@AS@%  
  12442. %@AS@%  /* Load new palette data */
  12443. %@AS@%  
  12444. %@AS@%  _pg_setpalette( palette_struct );%@AE@%%@NL@%
  12445. %@NL@%
  12446. Now when you display your bar or column chart, the first series appears
  12447. filled with the striped pattern shown in Table 11.3.  %@NL@%
  12448. %@NL@%
  12449. Palette structures are used differently with pie charts. Instead of
  12450. clarifying multiple series, fill patterns, line styles, and colors, palette
  12451. structures are used to distinguish individual slices in a pie chart.
  12452. Palettes are recycled if the number of slices exceeds %@AB@%_PG_PALETTELEN%@AE@%. Thus,
  12453. the first palette dictates not only the appearance of the first slice, but
  12454. of slice number %@AB@%_PG_PALETTELEN%@AE@% as well. The second palette determines the
  12455. appearance of both the second slice and of slice number %@AB@%_PG_PALETTELEN%@AE@% + 1,
  12456. and so forth.%@CR:C6A00110014 @%  %@NL@%
  12457. %@NL@%
  12458. %@NL@%
  12459. %@3@%%@CR:C6A00110015 @%%@AB@%11.4.4  Character Pool%@AE@%%@EH@%%@NL@%
  12460. %@NL@%
  12461. The last member of a palette structure is an index number in a pool of ASCII
  12462. characters:  %@NL@%
  12463. %@NL@%
  12464. %@AS@%  char plotchar;%@AE@%%@NL@%
  12465. %@NL@%
  12466. The member %@AB@%plotchar%@AE@% represents plot points on line graphs and scatter
  12467. diagrams. Each palette uses a different character to distinguish plot points
  12468. between data series.  %@NL@%
  12469. %@NL@%
  12470. %@NL@%
  12471. %@2@%%@CR:C6A00110016 @%%@AB@%11.5  Customizing the Chart Environment%@AE@%%@EH@%%@NL@%
  12472. %@NL@%
  12473. The presentation graphics functions are designed to be flexible. You can use
  12474. the system of default values to produce professional-looking charts with a
  12475. minimum of programming effort. Or you can fine-tune the appearance of your
  12476. charts by overriding default values and initializing variables explicitly in
  12477. your program.  %@NL@%
  12478. %@NL@%
  12479. The header file PGCHART.H defines a structure type %@AB@%chartenv%@AE@%, which organizes
  12480. the chart environment variables. The chart environment describes everything
  12481. about a chart except the plots themselves. It is the blank page, in other
  12482. words, ready for plotting data. The environment determines the appearance of
  12483. text, axes, grid lines, and legends.  %@NL@%
  12484. %@NL@%
  12485. Colors and line styles in the chart environment are taken from palettes. In
  12486. this way, the appearance of titles and axis lines matches the colors and
  12487. line styles of plotted data series.  %@NL@%
  12488. %@NL@%
  12489. %@AU@% You can reset any variable in the environment.%@AE@%  %@NL@%
  12490. %@NL@%
  12491. Calling the %@AB@%_pg_defaultchart%@AE@% function fills the chart environment with
  12492. default values. Presentation graphics allows you to reset any variable in
  12493. the environment before displaying a chart. Except for adjusting the palette
  12494. values, all initialization of data is done through a %@AB@%chartenv%@AE@% type
  12495. structure.  %@NL@%
  12496. %@NL@%
  12497. The sample chart programs provided in Section 11.3, "Writing a Presentation
  12498. Graphics Program," illustrate how to adjust variables in the chart
  12499. environment. These programs create a structure %@AS@% env %@AE@% of type %@AB@%chartenv%@AE@%. The
  12500. structure %@AS@% env %@AE@% contains the chart environment variables, initialized by the
  12501. call to the %@AB@%_pg_defaultchart%@AE@% function. Environment variables such as the
  12502. chart title are then given specific values, as in  %@NL@%
  12503. %@NL@%
  12504. %@AS@%  strcpy( env.maintitle.title, "Good Neighbor Grocery" );%@AE@%%@NL@%
  12505. %@NL@%
  12506. Environment variables that determine colors and line styles deserve special
  12507. mention. The chart environment holds several such variables, which can be
  12508. recognized by their names. For example, the variable %@AB@%titlecolor%@AE@% specifies
  12509. the color of title text. Similarly, the variable %@AB@%gridstyle%@AE@% specifies the
  12510. line style used to draw the chart grid.  %@NL@%
  12511. %@NL@%
  12512. These variables are index numbers, but do not refer directly to the color
  12513. pool or line pool. They correspond instead to palette numbers. If you set
  12514. %@AB@%titlecolor%@AE@% to 2, presentation graphics uses the color code in the second
  12515. palette to determine the title's color. Thus, the title in this case would
  12516. be the same color as the chart's second data series. If you change the color
  12517. code in the palette, you'll also change the title's color.  %@NL@%
  12518. %@NL@%
  12519. A structure of type %@AB@%chartenv%@AE@% consists of four types of secondary structures.
  12520. The file PGCHART.H type-defines these secondary structures: %@AB@%titletype%@AE@%,
  12521. %@AB@%axistype%@AE@%, %@AB@%windowtype%@AE@%, and %@AB@%legendtype%@AE@%.  %@NL@%
  12522. %@NL@%
  12523. The remainder of this section describes the chart environment of
  12524. presentation graphics. It first examines structures of the four secondary
  12525. structures that make up the chart environment structure. The section
  12526. concludes with a description of the %@AB@%chartenv%@AE@% structure type. Each section
  12527. begins with a brief explanation of the structure's purpose, followed by a
  12528. listing of the structure type definition as it appears in the PGCHART.H
  12529. file. All symbolic constants are defined in the file PGCHART.H.  %@NL@%
  12530. %@NL@%
  12531. %@NL@%
  12532. %@3@%%@CR:C6A00110017 @%%@AB@%11.5.1  titletype Structures%@AE@%%@EH@%%@NL@%
  12533. %@NL@%
  12534. Structures of type %@AB@%titletype%@AE@% determine text, color, and placement of titles
  12535. appearing in the graph. The PGCHART.H file defines the structure type as  %@NL@%
  12536. %@NL@%
  12537. %@AS@%  typedef struct 
  12538. %@AS@%  {
  12539. %@AS@%     char     title[_PG_TITLELEN];  /* Title text */
  12540. %@AS@%     short    titlecolor;           /* Palette color
  12541. %@AS@%                                       for title text */
  12542. %@AS@%     short    justify;              /* _PG_LEFT, _PG_CENTER,
  12543. %@AS@%                                       _PG_RIGHT */
  12544. %@AS@%  } titletype;%@AE@%%@NL@%
  12545. %@NL@%
  12546. The following list describes %@AB@%titletype%@AE@% members:  %@NL@%
  12547. %@NL@%
  12548. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  12549. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12550. %@AI@%justify%@AE@%                           An integer specifying how the title is 
  12551.                                   justified within the chart window. The 
  12552.                                   symbolic constants defined
  12553.                                   in PGCHART.H for this variable are %@AB@%%@AE@%
  12554.                                   %@AB@%_PG_LEFT%@AE@%,%@AB@%%@AE@%
  12555.                                   %@AB@%_PG_CENTER%@AE@%, and %@AB@%_PG_RIGHT%@AE@%.
  12556.  
  12557. %@AI@%titlecolor%@AE@%                        An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@%
  12558.                                   that specifies a title's color. The 
  12559.                                   default value for%@AI@%%@AE@%
  12560.                                   %@AI@%titlecolor%@AE@% is 1.
  12561.  
  12562. %@AI@%title%@AE@%%@AB@%[_PG_TITLELEN]%@AE@%               A character array containing title text.
  12563.                                   For example, if %@AS@% env %@AE@% is a structure of 
  12564.                                   type%@AB@% chartenv%@AE@%, then %@AS@% env.maintitle.title%@AE@%
  12565.                                   %@AS@%%@AE@% holds the character string used for the
  12566.                                   main title of the chart. Similarly, %@AS@%%@AE@%
  12567.                                   %@AS@%env.xaxis.axistitle.title %@AE@% contains the %@AI@%%@AE@%
  12568.                                   %@AI@%x%@AE@% axis title. The number of characters 
  12569.                                   in a title must be one less than %@AB@%%@AE@%
  12570.                                   %@AB@%_PG_TITLELEN%@AE@% to allow room for a null 
  12571.                                   terminator. 
  12572.  
  12573. %@NL@%
  12574. %@3@%%@CR:C6A00110018 @%%@AB@%11.5.2  axistype Structures%@AE@%%@EH@%%@NL@%
  12575. %@NL@%
  12576. Structures of type %@AB@%axistype%@AE@% contain variables for the axes such as color,
  12577. scale, grid style, and tick marks. The PGCHART.H file defines the structure
  12578. type as the following:  %@NL@%
  12579. %@NL@%
  12580. %@AS@%  typedef struct 
  12581. %@AS@%  {
  12582. %@AS@%     short       grid;          /* TRUE=grid lines drawn;
  12583. %@AS@%                                   FALSE=no lines */
  12584. %@AS@%     short       gridstyle;     /* Style bytes for grid */
  12585. %@AS@%     titletype   axistitle;     /* Title definition
  12586. %@AS@%                                   for axis */
  12587. %@AS@%     short       axiscolor;     /* Color for axis */
  12588. %@AS@%     short       labeled;       /* TRUE=ticks marks and titles
  12589. %@AS@%                                   drawn */
  12590. %@AS@%     short       rangetype;     /* _PG_LINEARAXIS,
  12591. %@AS@%                                   _PG_LOGAXIS */
  12592. %@AS@%     float       logbase;       /* Base used if log axis */
  12593. %@AS@%     short       autoscale;     /* TRUE=next 7 values
  12594. %@AS@%                                   calculated by system */
  12595. %@AS@%     float       scalemin;      /* Minimum value of scale */
  12596. %@AS@%     float       scalemax;      /* Maximum value of scale */
  12597. %@AS@%     float       scalefactor;   /* Scale factor for data on
  12598. %@AS@%                                   this axis */
  12599. %@AS@%     titletype   scaletitle;    /* Title definition for
  12600. %@AS@%                                   scaling factor */
  12601. %@AS@%     float       ticinterval;   /* Distance between tick marks
  12602. %@AS@%                                   (world coord.) */
  12603. %@AS@%     short       ticformat;     /* _PG_EXPFORMAT or
  12604. %@AS@%                                   _PG_DECFORMAT */
  12605. %@AS@%     short       ticdecimals;   /* Number of decimals for tick
  12606. %@AS@%                                   labels (max=9) */
  12607. %@AS@%  } axistype;%@AE@%%@NL@%
  12608. %@NL@%
  12609. The following list describes %@AB@%axistype%@AE@% member variables:  %@NL@%
  12610. %@NL@%
  12611. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  12612. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12613. %@AI@%autoscale%@AE@%                         A Boolean variable. If %@AI@%autoscale%@AE@% is set 
  12614.                                   to %@AB@%TRUE%@AE@%, 
  12615.                                   presentation graphics automatically 
  12616.                                   determines
  12617.                                   values for %@AI@%scalefactor%@AE@%, %@AI@%scalemax%@AE@%, %@AI@%%@AE@%
  12618.                                   %@AI@%scalemin%@AE@%, %@AI@%%@AE@%
  12619.                                   %@AI@%scaletitle%@AE@%, %@AI@%ticdecimals%@AE@%, %@AI@%ticformat%@AE@%, and %@AI@%%@AE@%
  12620.                                   %@AI@%ticinterval%@AE@% 
  12621.                                   (see below). If %@AI@%autoscale%@AE@% equals %@AB@%FALSE%@AE@%, 
  12622.                                   these seven variables must be specified 
  12623.                                   in your program.
  12624.  
  12625. %@AI@%axiscolor%@AE@%                         An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  12626.                                   that specifies the color used for the 
  12627.                                   axis and parallel grid lines. (See 
  12628.                                   description for %@AI@%gridstyle%@AE@% below.) Note 
  12629.                                   that this member does not determine the 
  12630.                                   color of
  12631.                                   the axis title. That selection is made 
  12632.                                   through the%@AB@%%@AE@%
  12633.                                   %@AB@%axistitle%@AE@% structure.
  12634.  
  12635. %@AI@%axistitle%@AE@%                         A %@AB@%titletype%@AE@% structure that defines the 
  12636.                                   title of the associated axis. The title 
  12637.                                   of the %@AI@%y%@AE@% axis displays vertically to the
  12638.                                   left of the %@AI@%y%@AE@% axis, and the title of the
  12639.                                   %@AI@%x%@AE@% axis displays horizontally below the %@AI@%x%@AE@%
  12640.                                   axis.
  12641.  
  12642. %@AI@%grid%@AE@%                              A Boolean true/false value that 
  12643.                                   determines whether grid lines are drawn 
  12644.                                   for the associated axis. Grid lines span
  12645.                                   the data window perpendicular to the 
  12646.                                   axis.
  12647.  
  12648. %@AI@%gridstyle%@AE@%                         An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  12649.                                   that specifies the grid's line style. 
  12650.                                   Lines can be solid, dashed, dotted, or 
  12651.                                   some combination. The default value for %@AI@%%@AE@%
  12652.                                   %@AI@%gridstyle%@AE@% is 1. 
  12653.  
  12654.                                   Note that the color of the parallel axis
  12655.                                   determines the color of the grid lines. 
  12656.                                   Thus, the %@AI@%x%@AE@% axis grid is the same color 
  12657.                                   as the %@AI@%y%@AE@% axis, and the %@AI@%y%@AE@% axis grid is 
  12658.                                   the same color as the %@AI@%x%@AE@% axis.
  12659.  
  12660. %@AI@%labeled%@AE@%                           A Boolean value that determines whether 
  12661.                                   tick marks and labels are drawn on the 
  12662.                                   axis. Axis labels should not be confused
  12663.                                   with axis titles. Axis labels are 
  12664.                                   numbers or descriptions such as "23.2" 
  12665.                                   or "January" attached to each tick mark.
  12666.  
  12667. %@AI@%logbase%@AE@%                           If%@AI@% rangetype%@AE@% is logarithmic, the %@AI@%logbase%@AE@%
  12668.                                   variable determines the log base used to
  12669.                                   scale the axis. The default value is 10.
  12670.  
  12671. %@AI@%rangetype%@AE@%                         An integer that determines whether the 
  12672.                                   scale of the axis is linear or 
  12673.                                   logarithmic. The variable %@AI@%rangetype%@AE@% 
  12674.                                   applies only to value data.
  12675.  
  12676.                                   Specify a linear scale with %@AB@%%@AE@%
  12677.                                   %@AB@%_PG_LINEARAXIS%@AE@%. A linear scale is best 
  12678.                                   when the difference between axis minimum
  12679.                                   and maximum is relatively small. For
  12680.                                   example, a linear axis range 0 - 10 
  12681.                                   results in 10 tick marks evenly spaced 
  12682.                                   along the axis.
  12683.  
  12684.                                   Use %@AB@%_PG_LOGAXIS%@AE@% to specify a logarithmic
  12685.                                   %@AI@%rangetype%@AE@%. Logarithmic scales are useful
  12686.                                   when
  12687.                                   the range is very large or when the data
  12688.                                   varies exponentially. Line graphs of 
  12689.                                   exponentially varying data can be made 
  12690.                                   straight with a logarithmic%@AI@%%@AE@%
  12691.                                   %@AI@%rangetype%@AE@%.
  12692.  
  12693. %@AI@%scalefactor%@AE@%                       All numeric data are scaled by dividing 
  12694.                                   each
  12695.                                   value by %@AI@%scalefactor%@AE@%. For relatively 
  12696.                                   small values,%@AI@%%@AE@%
  12697.                                   %@AI@%scalefactor%@AE@% should be 1, which is the 
  12698.                                   default. But data with large values 
  12699.                                   should be scaled by an appropriate 
  12700.                                   factor. For example, data in the range
  12701.                                   2 million - 20 million should be plotted
  12702.                                   with%@AI@%%@AE@%
  12703.                                   %@AI@%scalemin%@AE@% set to 2, %@AI@%scalemax%@AE@% set to 20, 
  12704.                                   and%@AI@%%@AE@%
  12705.                                   %@AI@%scalefactor%@AE@% set to 1 million.
  12706.  
  12707.                                   If %@AI@%autoscale%@AE@% is set to %@AB@%TRUE%@AE@%, 
  12708.                                   presentation graphics automatically 
  12709.                                   determines a suitable value for%@AI@%%@AE@%
  12710.                                   %@AI@%scalefactor%@AE@% based on the range of data 
  12711.                                   to be plotted. Presentation graphics 
  12712.                                   selects only values that are a factor of
  12713.                                   1 thousand─that is, values such as 1 
  12714.                                   thousand, 1 million, or 1 billion. It 
  12715.                                   then labels the%@AI@%%@AE@%
  12716.                                   %@AI@%scaletitle%@AE@% appropriately (see below). If
  12717.                                   you desire some other value for scaling,
  12718.                                   you must set %@AI@%autoscale%@AE@% to %@AB@%FALSE%@AE@% and set %@AI@%%@AE@%
  12719.                                   %@AI@%scalefactor%@AE@% to the desired scaling value.
  12720.  
  12721. %@AI@%scalemax%@AE@%                          Highest value represented by the axis.
  12722.  
  12723. %@AI@%scalemin%@AE@%                          Lowest value represented by the axis.
  12724.  
  12725. %@AI@%scaletitle%@AE@%                        A %@AB@%titletype%@AE@% structure defining a string 
  12726.                                   of text that 
  12727.                                   describes the value of %@AI@%scalefactor%@AE@%. If %@AI@%%@AE@%
  12728.                                   %@AI@%autoscale%@AE@% is %@AB@%TRUE%@AE@%, presentation graphics
  12729.                                   automatically writes a scale description
  12730.                                   to %@AI@%scaletitle%@AE@%. If%@AI@% autoscale%@AE@% equals %@AB@%FALSE%@AE@%
  12731.                                   and %@AI@%scalefactor%@AE@% is 1, %@AI@%scaletitle.title%@AE@% 
  12732.                                   should be blank. Otherwise your program 
  12733.                                   should copy an appropriate scale 
  12734.                                   description to %@AI@%scaletitle.title%@AE@%, such as
  12735.                                   "( x 1000)," "(in millions of units)," 
  12736.                                   or "times 10 thousand dollars."
  12737.  
  12738.                                   For the %@AI@%y%@AE@% axis, the %@AI@%scaletitle%@AE@% text 
  12739.                                   displays vertically between the axis 
  12740.                                   title and the %@AI@%y%@AE@% axis. For the %@AI@%x%@AE@% axis, 
  12741.                                   the scale title appears below the %@AI@%x%@AE@% axis
  12742.                                   title.
  12743.  
  12744. %@AI@%ticdecimals %@AE@%                      Number of digits to display after the 
  12745.                                   decimal point in tick labels. Maximum 
  12746.                                   value is 9. (This variable applies only 
  12747.                                   to axes with value data and is ignored 
  12748.                                   for the category axis.)
  12749.  
  12750. %@AI@%ticformat%@AE@%                         An integer that determines format of the
  12751.                                   labels
  12752.                                   assigned to each tick mark. Set %@AI@%%@AE@%
  12753.                                   %@AI@%ticformat%@AE@%  to%@AB@%%@AE@%
  12754.                                   %@AB@%_PG_EXPFORMAT%@AE@% for exponential format or
  12755.                                   to %@AB@%_PG_DECFORMAT%@AE@% for decimal. The 
  12756.                                   default is %@AB@%_PG_DECFORMAT%@AE@%. (This variable
  12757.                                   applies only to axes with value data and
  12758.                                   is ignored for the category axis.)
  12759.  
  12760. %@AI@%ticinterval%@AE@%                       Sets interval between tick marks on the 
  12761.                                   axis. The tick interval is measured in 
  12762.                                   the same units as the numeric data 
  12763.                                   associated with the axis. For example, 
  12764.                                   if 2 sequential tick marks correspond to
  12765.                                   the values 20 and 25, the tick interval 
  12766.                                   between them is 5. (This variable 
  12767.                                   applies only to axes with value data and
  12768.                                   is ignored for the category axis.)
  12769.  
  12770. %@NL@%
  12771. %@3@%%@CR:C6A00110019 @%%@AB@%11.5.3  windowtype Structures%@AE@%%@EH@%%@NL@%
  12772. %@NL@%
  12773. Structures of type %@AB@%windowtype%@AE@% contain sizes, locations, and color codes for
  12774. the three windows produced by presentation graphics: the chart window, the
  12775. data window, and the legend. Windows are located on the screen relative to
  12776. the screen's logical origin. By changing the logical origin, you can display
  12777. charts that are partly or completely off the screen.  %@NL@%
  12778. %@NL@%
  12779. The PGCHART.H file defines %@AB@%windowtype%@AE@% as the following:  %@NL@%
  12780. %@NL@%
  12781. %@AS@%  typedef struct 
  12782. %@AS@%  {
  12783. %@AS@%     short  x1;            /* Left edge of window in
  12784. %@AS@%                              pixels */
  12785. %@AS@%     short  y1;            /* Top edge of window in
  12786. %@AS@%                              pixels */
  12787. %@AS@%     short  x2;            /* Right edge of window in
  12788. %@AS@%                              pixels */
  12789. %@AS@%     short  y2;            /* Bottom edge of window in
  12790. %@AS@%                              pixels */
  12791. %@AS@%     short  border;        /* TRUE for border, FALSE
  12792. %@AS@%                              otherwise */
  12793. %@AS@%     short  background;    /* Internal palette color for
  12794. %@AS@%                              window background */
  12795. %@AS@%     short  borderstyle;   /* Style bytes for window
  12796. %@AS@%                              border */
  12797. %@AS@%     short  bordercolor;   /* Internal palette color for
  12798. %@AS@%                              window border */
  12799. %@AS@%  } windowtype;%@AE@%%@NL@%
  12800. %@NL@%
  12801. The following list describes %@AB@%windowtype%@AE@% member variables:  %@NL@%
  12802. %@NL@%
  12803. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  12804. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12805. %@AI@%background%@AE@%                        An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  12806.                                   that specifies the window's background 
  12807.                                   color. The default value for %@AI@%background%@AE@% 
  12808.                                   is 1.
  12809.  
  12810. %@AI@%border%@AE@%                            A Boolean variable that determines 
  12811.                                   whether a border frame is drawn around a
  12812.                                   window.
  12813.  
  12814. %@AI@%bordercolor%@AE@%                       An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  12815.                                   that specifies the color of the window's
  12816.                                   border frame. The default value is 1.
  12817.  
  12818. %@AI@%borderstyle%@AE@%                       An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  12819.                                   that specifies the line style of the 
  12820.                                   window's border frame. The default value
  12821.                                   is 1.
  12822.  
  12823. %@AI@%x1, y1, x2, y2%@AE@%                    Window coordinates in pixels. The 
  12824.                                   ordered pair
  12825.                                   (%@AI@%x1%@AE@%, %@AI@%y1%@AE@%) specifies the coordinate of the
  12826.                                   upper left corner of the window. The 
  12827.                                   ordered pair ( %@AI@%x2%@AE@%, %@AI@%y2%@AE@% ) specifies the 
  12828.                                   coordinate of the lower right corner.
  12829.  
  12830.                                   The reference point for the coordinates 
  12831.                                   depends on the type of window. The chart
  12832.                                   window is located relative to the 
  12833.                                   logical origin, usually the upper left 
  12834.                                   corner of the screen. The data and 
  12835.                                   legend windows are located relative to 
  12836.                                   the upper left corner of the chart 
  12837.                                   window. This allows you to change the 
  12838.                                   position of the chart window without 
  12839.                                   having to redefine coordinates for the 
  12840.                                   other two windows.
  12841.  
  12842. %@NL@%
  12843. %@3@%%@CR:C6A00110020 @%%@AB@%11.5.4  legendtype Structures%@AE@%%@EH@%%@NL@%
  12844. %@NL@%
  12845. Structures of type %@AB@%legendtype%@AE@% contain size, location, and colors of the
  12846. chart legend. The PGCHART.H file defines the structure type as the
  12847. following:  %@NL@%
  12848. %@NL@%
  12849. %@AS@%  typedef struct 
  12850. %@AS@%  {
  12851. %@AS@%     short      legend;        /* TRUE=draw legend;
  12852. %@AS@%                                  FALSE=no legend */
  12853. %@AS@%     short      place;         /* _PG_RIGHT, _PG_BOTTOM,
  12854. %@AS@%                                  _PG_OVERLAY */
  12855. %@AS@%     short      textcolor;     /* Palette color for text*/
  12856. %@AS@%     short      autosize;      /* TRUE=system calculates
  12857. %@AS@%                                  legend size */
  12858. %@AS@%     windowtype legendwindow;  /* Window definition for
  12859. %@AS@%                                  legend */
  12860. %@AS@%  } legendtype;%@AE@%%@NL@%
  12861. %@NL@%
  12862. The following list describes %@AB@%legendtype%@AE@% member variables:  %@NL@%
  12863. %@NL@%
  12864. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  12865. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12866. %@AI@%autosize%@AE@%                          A Boolean true/false variable that 
  12867.                                   determines whether presentation graphics
  12868.                                   is to automatically
  12869.                                   calculate the size of the legend. If %@AI@%%@AE@%
  12870.                                   %@AI@%autosize%@AE@% equals %@AB@%FALSE%@AE@%, the legend window
  12871.                                   must be specified in the %@AI@%legendwindow%@AE@% 
  12872.                                   structure (see below).
  12873.  
  12874. %@AI@%legend%@AE@%                            A Boolean true/false variable that 
  12875.                                   determines whether a legend is to appear
  12876.                                   on the chart. The %@AI@%legend%@AE@% variable is 
  12877.                                   ignored by functions that graph 
  12878.                                   single-series charts.
  12879.  
  12880. %@AI@%legendwindow%@AE@%                      A %@AB@%windowtype%@AE@% structure that defines 
  12881.                                   coordinates, background color, and 
  12882.                                   border frame for the legend. Coordinates
  12883.                                   given in %@AI@%legendwindow%@AE@% are ignored if %@AI@%%@AE@%
  12884.                                   %@AI@%autosize%@AE@% is set to %@AB@%TRUE%@AE@%.
  12885.  
  12886. %@AI@%place%@AE@%                             An integer that specifies the location 
  12887.                                   of the legend relative to the data 
  12888.                                   window. Setting %@AI@%place%@AE@% equal
  12889.                                   to the constant %@AB@%_PG_RIGHT%@AE@% positions the 
  12890.                                   legend
  12891.                                   to the right of the data window. Setting
  12892.                                   %@AI@%place%@AE@% to%@AB@%%@AE@%
  12893.                                   %@AB@%_PG_BOTTOM%@AE@% positions the legend below 
  12894.                                   the data window. Setting %@AI@%place%@AE@% to %@AB@%%@AE@%
  12895.                                   %@AB@%_PG_OVERLAY%@AE@% positions the legend within 
  12896.                                   the data window.
  12897.  
  12898.                                   These settings influence the size of the
  12899.                                   data window. If %@AI@%place%@AE@% equals %@AB@%_PG_RIGHT%@AE@% 
  12900.                                   or %@AB@%_PG_BOTTOM%@AE@%, presentation graphics 
  12901.                                   automatically sizes the data window to 
  12902.                                   accommodate the legend. If %@AI@%place%@AE@% equals %@AB@%%@AE@%
  12903.                                   %@AB@%_PG_OVERLAY%@AE@%, the data window is sized 
  12904.                                   without regard to the legend.
  12905.  
  12906. %@AI@%textcolor%@AE@%                         An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  12907.                                   that specifies the color of text within 
  12908.                                   the legend window.
  12909.  
  12910. %@NL@%
  12911. %@3@%%@CR:C6A00110021 @%%@AB@%11.5.5  chartenv Structures%@AE@%%@EH@%%@NL@%
  12912. %@NL@%
  12913. A structure of type%@AB@% chartenv%@AE@% defines the chart environment. The following
  12914. listing shows that a %@AB@%chartenv%@AE@% type structure consists almost entirely of
  12915. structures of the four types described above.  %@NL@%
  12916. %@NL@%
  12917. The PGCHART.H file defines the %@AB@%chartenv%@AE@% structure type as the following:  %@NL@%
  12918. %@NL@%
  12919. %@AS@%  typedef struct 
  12920. %@AS@%  {
  12921. %@AS@%     short       charttype;     /* Chart type */
  12922. %@AS@%     short       chartstyle;    /* Chart style */
  12923. %@AS@%     windowtype  chartwindow;   /* Window definition for
  12924. %@AS@%                                   overall chart */
  12925. %@AS@%     windowtype  datawindow;    /* Window definition for data
  12926. %@AS@%                                   part of chart */
  12927. %@AS@%     titletype   maintitle;     /* Main chart title */
  12928. %@AS@%     titletype   subtitle;      /* Chart subtitle */
  12929. %@AS@%     axistype    xaxis;         /* Definition for x axis */
  12930. %@AS@%     axistype    yaxis;         /* Definition for y axis */
  12931. %@AS@%     legendtype  legend;        /* Definition for legend */
  12932. %@AS@%  } chartenv;%@AE@%%@NL@%
  12933. %@NL@%
  12934. %@AU@% Initialize the chart environment with the _pg_defaultchart function.%@AE@%  %@NL@%
  12935. %@NL@%
  12936. The data in a %@AB@%chartenv%@AE@% type structure is initialized by calling the function%@AB@%
  12937. %@AB@%_pg_defaultchart%@AE@%. If your program does not call %@AB@%_pg_defaultchart%@AE@%, it must
  12938. explicitly define every variable in the chart environment─a tedious
  12939. procedure. The recommended method for adjusting the appearance of your chart
  12940. is to initialize variables for the proper chart type by calling the
  12941. %@AB@%_pg_defaultchart%@AE@% function, and then to reassign selected environment
  12942. variables such as titles.  %@NL@%
  12943. %@NL@%
  12944. The following list describes %@AB@%chartenv%@AE@% member variables:  %@NL@%
  12945. %@NL@%
  12946. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  12947. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12948. %@AI@%chartstyle%@AE@%                        An integer that determines the style of 
  12949.                                   the chart
  12950.                                   (see Table 11.2). Legal values for %@AI@%%@AE@%
  12951.                                   %@AI@%chartstyle%@AE@% are %@AB@%_PG_PERCENT%@AE@% and %@AB@%%@AE@%
  12952.                                   %@AB@%_PG_NOPERCENT%@AE@% for pie charts; %@AB@%%@AE@%
  12953.                                   %@AB@%_PG_PLAINBARS%@AE@% and %@AB@%_PG_STACKEDBARS%@AE@% for 
  12954.                                   bar and column charts; and %@AB@%_PG_POINTONLY%@AE@%
  12955.                                   and  %@AB@%_PG_POINTANDLINE%@AE@% for line graphs 
  12956.                                   and scatter diagrams. This variable 
  12957.                                   corresponds to the third argument for 
  12958.                                   the %@AB@%_pg_defaultchart%@AE@% function.
  12959.  
  12960. %@AI@%charttype%@AE@%                         An integer that determines the type of 
  12961.                                   chart displayed. The value of %@AI@%charttype%@AE@% 
  12962.                                   is %@AB@%_PG_BARCHART%@AE@%, %@AB@%_PG_COLUMNCHART%@AE@%, %@AB@%%@AE@%
  12963.                                   %@AB@%_PG_LINECHART%@AE@%, %@AB@%_PG_SCATTERCHART%@AE@%, or %@AB@%%@AE@%
  12964.                                   %@AB@%_PG_PIECHART%@AE@%. This variable corresponds 
  12965.                                   to the second argument for the %@AB@%%@AE@%
  12966.                                   %@AB@%_pg_defaultchart%@AE@% function.
  12967.  
  12968. %@AI@%chartwindow%@AE@%                       A %@AB@%windowtype%@AE@% structure that defines the 
  12969.                                   appearance of the chart window.
  12970.  
  12971. %@AI@%datawindow%@AE@%                        A %@AB@%windowtype%@AE@% structure that defines the 
  12972.                                   appearance of the data window.
  12973.  
  12974. %@AI@%legend%@AE@%                            A %@AB@%legendtype%@AE@% structure that defines the 
  12975.                                   appearance of the legend window.
  12976.  
  12977. %@AI@%maintitle%@AE@%                         A %@AB@%titletype%@AE@% structure that defines the 
  12978.                                   appearance of the main title of the 
  12979.                                   chart.
  12980.  
  12981. %@AI@%subtitle%@AE@%                          A %@AB@%titletype%@AE@% structure that defines the 
  12982.                                   appearance of the chart's subtitle.
  12983.  
  12984. %@AI@%xaxis%@AE@%                             An %@AB@%axistype%@AE@% structure that defines the 
  12985.                                   appearance of the %@AI@%x%@AE@% axis. (This variable
  12986.                                   is not applicable for pie charts.)
  12987.  
  12988. %@AI@%yaxis%@AE@%                             An %@AB@%axistype%@AE@% structure that defines the 
  12989.                                   appearance of the %@AI@%y%@AE@% axis. (This variable
  12990.                                   is not applicable for pie charts.)
  12991.  
  12992.                                   
  12993.  
  12994.   %@NL@%
  12995. %@NL@%
  12996. %@NL@%
  12997. %@NL@%
  12998. %@NL@%
  12999. %@NL@%
  13000. %@NL@%
  13001. %@CR:C6A00120001 @%%@1@%%@AB@%Chapter 12  Programming with Mixed Languages%@AE@%%@EH@%%@NL@%
  13002. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13003. %@NL@%
  13004. There are times when your Microsoft C programs need to call programs written
  13005. in other languages or when programs written in other languages need to call
  13006. your C functions. This is called mixed-language programming. For example,
  13007. when a particular subprogram is available commercially in a language other
  13008. than C or when algorithms are described more naturally in a different
  13009. language, you need to use more than one language.  %@NL@%
  13010. %@NL@%
  13011. This chapter describes the elements of mixed-language programming─how to
  13012. make calls from programs written in one language to routines written in
  13013. another.  %@NL@%
  13014. %@NL@%
  13015. %@NL@%
  13016. %@2@%%@CR:C6A00120002 @%%@AB@%12.1  Making Mixed-Language Calls%@AE@%%@EH@%%@NL@%
  13017. %@NL@%
  13018. Mixed-language programming always involves a call to a function, procedure,
  13019. or subroutine. For example, a BASIC main module may need to execute a
  13020. specific task that you would like to program separately. Instead of calling
  13021. a BASIC subprogram, however, you decide to call a C function.  %@NL@%
  13022. %@NL@%
  13023. Mixed-language calls involve calling functions in separate modules. Instead
  13024. of compiling all of your source modules with the same compiler, you use
  13025. different compilers. In the instance mentioned above, you would compile the
  13026. mainmodule source file with the BASIC compiler, another source file (written
  13027. in C) with the C compiler, and then link the two object files.  %@NL@%
  13028. %@NL@%
  13029. Figure 12.1 illustrates how the syntax of a mixed-language call works, using
  13030. the instance mentioned above.  %@NL@%
  13031. %@NL@%
  13032. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  13033. %@NL@%
  13034. In Figure 12.1, the BASIC call to C is %@AS@% CALL Prn%@AE@%, similar to a call to a
  13035. BASIC subprogram. There are two differences between this mixed-language call
  13036. and a call between two BASIC modules:  %@NL@%
  13037. %@NL@%
  13038. %@NL@%
  13039.   1.  The subprogram %@AS@% Prn %@AE@% is implemented in C, using standard C syntax.%@NL@%
  13040. %@NL@%
  13041.   2.  The implementation of the call in BASIC is affected by the %@AB@%DECLARE%@AE@%
  13042.       statement, which uses the %@AB@%CDECL%@AE@% keyword to create compatibility with
  13043.       C. The %@AB@%DECLARE%@AE@% statement (which is described in detail in the
  13044.       %@AI@%Microsoft BASIC Language Reference%@AE@% and the %@AI@%Microsoft BASIC
  13045. %@AI@%      Programmer's Guide%@AE@%) is an example of a mixed-language "interface"
  13046.       statement. These interface statements override default naming and
  13047.       calling conventions. Each language provides its own form of interface.%@NL@%
  13048. %@NL@%
  13049. %@NL@%
  13050. You can make mixed-language calls to routines regardless of whether they
  13051. have return values. (In this chapter, "routine" refers to any function,
  13052. procedure, or subroutine that can be called from another module.)  %@NL@%
  13053. %@NL@%
  13054. Table 12.1 shows the correspondence between calls to routines in different
  13055. languages.  %@NL@%
  13056. %@NL@%
  13057. %@AB@%Table 12.1  %@AB@%Language Equivalents for Routine Calls%@AE@%%@AE@%
  13058.  
  13059. %@TH:   8   553 02 20 21 35 @%
  13060. Language            Return Value         No Return Value
  13061. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13062. Assembly Language   Procedure            Procedure
  13063. BASIC               FUNCTION procedure   Subprogram
  13064. C                   function             (%@AB@%void%@AE@%) function
  13065. FORTRAN             FUNCTION             SUBROUTINE
  13066. Pascal              Function             Procedure
  13067. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13068. %@TE:   8   553 02 20 21 35 @%
  13069.  
  13070. For example, a C module can make a subprogram call to a FORTRAN subroutine.
  13071. You can prototype a FORTRAN subroutine as a function with a %@AB@% void%@AE@% type.  %@NL@%
  13072. %@NL@%
  13073. ────────────────────────────────────────────────────────────────────────────%@NL@%
  13074. NOTE
  13075.  
  13076. %@AI@%BASIC %@AI@%DEF FN%@AE@%%@AI@% functions and GOSUB%@AE@%%@AI@% subroutines cannot be called from another
  13077. %@AI@%language.%@AE@%%@AE@%%@NL@%
  13078. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  13079. %@NL@%
  13080. %@NL@%
  13081. %@2@%%@CR:C6A00120003 @%%@AB@%12.2  Language Convention Requirements%@AE@%%@EH@%%@NL@%
  13082. %@NL@%
  13083. To mix languages, the calling program must observe the same conventions as
  13084. the called program. The conventions described in this section govern the
  13085. following:  %@NL@%
  13086. %@NL@%
  13087. %@NL@%
  13088.   ■   How compilers treat identifiers, including function and variable names
  13089.       (naming convention)%@NL@%
  13090. %@NL@%
  13091.   ■   How the subprogram call is implemented (calling convention)%@NL@%
  13092. %@NL@%
  13093.   ■   How parameters are passed (parameter-passing convention)%@NL@%
  13094. %@NL@%
  13095. %@NL@%
  13096. %@NL@%
  13097. %@3@%%@CR:C6A00120004 @%%@AB@%12.2.1  Naming Convention Requirement%@AE@%%@EH@%%@NL@%
  13098. %@NL@%
  13099. Both the calling program and the called subprogram must agree on the names
  13100. of identifiers. Identifiers can refer to subprograms (functions, procedures,
  13101. and subroutines) or to variables that have a public or global scope. Each
  13102. language alters the names of identifiers.%@CR:C6A00120005 @%  %@NL@%
  13103. %@NL@%
  13104. The term "naming convention" refers to the way a compiler alters the name of
  13105. the routine before placing it in an object file. Languages may alter the
  13106. identifier names differently. You can choose between several naming
  13107. conventions to ensure that the names in the calling program agree with those
  13108. in the called program. If the names of called routines are stored
  13109. differently in each object file, the linker will not be able to find a
  13110. match. It will instead report unresolved external references.  %@NL@%
  13111. %@NL@%
  13112. Microsoft compilers place machine code into object files; they also place
  13113. the names of all publicly accessed routines and variables in object files.
  13114. The linker can then compare the name of a routine called in one module with
  13115. the name of a routine defined in another module, and recognize a match.
  13116. Names are stored in the ASCII (American Standard Code for Information
  13117. Interchange) character set.  %@NL@%
  13118. %@NL@%
  13119. %@AU@% Some languages translate names to uppercase.%@AE@%  %@NL@%
  13120. %@NL@%
  13121. BASIC, FORTRAN, and Pascal use similar naming conventions. They translate
  13122. each letter to uppercase. BASIC type declaration characters (%, &, !, #, $)
  13123. are dropped.  %@NL@%
  13124. %@NL@%
  13125. Each language recognizes a different number of characters. FORTRAN
  13126. recognizes the first 31 characters of any name (unless identifier names are
  13127. truncated), Pascal the first 8, and BASIC the first 40. If a name is longer
  13128. than the language will recognize, additional characters are simply not
  13129. placed in the object file.  %@NL@%
  13130. %@NL@%
  13131. ────────────────────────────────────────────────────────────────────────────%@NL@%
  13132. NOTE
  13133.  
  13134. %@AI@%Versions of Microsoft FORTRAN previous to version 5.0 truncated identifiers
  13135. %@AI@%to six characters. As of version 5.0, FORTRAN retains up to 31 characters of
  13136. %@AI@%significance unless you use the /4Yt option.%@AE@%%@NL@%
  13137. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  13138. %@NL@%
  13139. %@AU@% C is a case-sensitive language.%@AE@%  %@NL@%
  13140. %@NL@%
  13141. The C compiler does not translate any letters to uppercase. It inserts a
  13142. leading underscore ( _ ) in front of the name of each routine. C recognizes
  13143. the first 31 characters of a name.  %@NL@%
  13144. %@NL@%
  13145. Differences in naming conventions are dealt with automatically by
  13146. mixedlanguage keywords, as long as you follow two rules:%@CR:C6A00120006 @%  %@NL@%
  13147. %@NL@%
  13148. %@NL@%
  13149.   1.  If you use any FORTRAN routines that were compiled with the /4Yt
  13150.       command-line option or with the %@AB@%$TRUNCATE%@AE@% metacommand enabled, make
  13151.       all names 6 characters or less. Make all names 6 characters or less
  13152.       when using FORTRAN routines compiled with versions of the FORTRAN
  13153.       compiler prior to 5.0.%@NL@%
  13154. %@NL@%
  13155.   2.  Do not use the /NOIGNORECASE linker option (which causes the linker to
  13156.       treat identifiers in a case-sensitive manner). With C modules, this
  13157.       means that you must be careful not to rely upon differences between
  13158.       uppercase and lowercase letters when programming.%@NL@%
  13159. %@NL@%
  13160. %@STUB@%      CL automatically uses the /NOIGNORECASE option when linking. To solve
  13161.       the problems created by this behavior, either link separately with the
  13162.       LINK utility, or use all lowercase letters in your C function names
  13163.       and public variables (global variables that are not declared as
  13164.       static).%@NL@%
  13165. %@NL@%
  13166. %@NL@%
  13167. ────────────────────────────────────────────────────────────────────────────%@NL@%
  13168. NOTE
  13169.  
  13170. %@AI@%If you use the command-line option /Gc (generate Pascal-style function
  13171. %@AI@%calls) when you compile, or if you declare a function or variable with the
  13172. %@AB@%_pascal%@AE@%%@AI@% keyword, the compiler will translate your identifiers to uppercase.%@AE@%%@AE@%%@NL@%
  13173. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  13174. %@NL@%
  13175. Figure 12.2 illustrates a complete mixed-language development example,
  13176. showing how naming conventions enter into the process.  %@NL@%
  13177. %@NL@%
  13178. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  13179. %@NL@%
  13180. In Figure 12.2, note that the BASIC compiler inserts a leading underscore in
  13181. front of %@AS@% Prn %@AE@% as it places the name into the object file, because the %@AB@%CDECL%@AE@%
  13182. keyword directs the BASIC compiler to use the C naming convention. BASIC
  13183. will also convert all letters to lowercase when this keyword is used.
  13184. (Converting letters to lowercase is not part of the C naming convention;
  13185. however, it is consistent with the programming style of many C programs.)%@CR:C6A00120007 @%  %@NL@%
  13186. %@NL@%
  13187. %@NL@%
  13188. %@3@%%@CR:C6A00120008 @%%@AB@%12.2.2  Calling Convention Requirement%@AE@%%@EH@%%@NL@%
  13189. %@NL@%
  13190. The term "calling convention" refers to the way a language implements a
  13191. call. The choice of calling convention affects the machine instructions that
  13192. a compiler generates to execute (and return from) a function, procedure, or
  13193. subroutine call.%@CR:C6A00120009 @%  %@NL@%
  13194. %@NL@%
  13195. It is crucial that the two routines concerned (the routine issuing a call
  13196. and the routine being called) use the same protocol. Otherwise, the
  13197. processor may receive inconsistent instructions, causing the program to
  13198. behave incorrectly.  %@NL@%
  13199. %@NL@%
  13200. The use of a calling convention affects programming in three ways:  %@NL@%
  13201. %@NL@%
  13202. %@NL@%
  13203.   1.  The calling routine uses a calling convention to determine the order
  13204.       in which to pass arguments (parameters) to another routine. This
  13205.       convention can be specified in a mixed-language interface statement or
  13206.       declaration.%@NL@%
  13207. %@NL@%
  13208.   2.  The called routine uses a calling convention to determine the order in
  13209.       which to receive the parameters passed to it. In most languages, this
  13210.       convention can be specified in the routine's heading. BASIC, however,
  13211.       always uses its own convention to receive parameters.%@NL@%
  13212. %@NL@%
  13213.   3.  Both the calling routine and the called routine must agree on which of
  13214.       them is responsible for adjusting the stack after all parameters are
  13215.       removed.%@NL@%
  13216. %@NL@%
  13217. %@NL@%
  13218. In other words, each call to a routine uses a certain calling convention;
  13219. each routine heading specifies or assumes some calling convention. The two
  13220. conventions must be compatible. With all languages except BASIC, it is
  13221. possible to change the calling convention at the point of the call or at the
  13222. declaration of the called routine. Usually, however, it is easier to adopt
  13223. the convention of the called routine. For example, a C function would use
  13224. its own convention to call another C function, and would use the Pascal
  13225. convention to call Pascal.  %@NL@%
  13226. %@NL@%
  13227. BASIC, FORTRAN, and Pascal use the same standard calling convention. C uses
  13228. a different convention.  %@NL@%
  13229. %@NL@%
  13230. %@NL@%
  13231. %@4@%%@AB@%Effects of Calling Conventions%@AE@%%@EH@%%@NL@%
  13232. %@NL@%
  13233. Calling conventions dictate three things:%@CR:C6A00120010 @%%@CR:C6A00120011 @%  %@NL@%
  13234. %@NL@%
  13235. %@NL@%
  13236.   1.  The way parameters are communicated from one routine to another (in
  13237.       Microsoft mixed-language programming, parameters or pointers to the
  13238.       parameters are passed on the stack)%@NL@%
  13239. %@NL@%
  13240.   2.  The order in which parameters are passed from one routine to another%@NL@%
  13241. %@NL@%
  13242.   3.  The part of the program responsible for adjusting the stack%@NL@%
  13243. %@NL@%
  13244. %@NL@%
  13245. %@AU@% Some languages pass parameters in a different order than C.%@AE@%  %@NL@%
  13246. %@NL@%
  13247. The BASIC, FORTRAN and Pascal calling conventions push parameters onto the
  13248. stack in the order in which they appear in the source code. For example, the
  13249. BASIC statement  %@NL@%
  13250. %@NL@%
  13251. %@AS@%  CALL Calc( A, B )%@AE@%%@NL@%
  13252. %@NL@%
  13253. pushes argument %@AS@% A %@AE@% onto the stack before it pushes %@AS@% B%@AE@%. These conventions
  13254. also specify that the stack is adjusted by the called routine just before
  13255. returning control to the caller.  %@NL@%
  13256. %@NL@%
  13257. The C calling convention pushes parameters onto the stack in the reverse
  13258. order from their appearance in the source code. For example, the C function
  13259. call  %@NL@%
  13260. %@NL@%
  13261. %@AS@%  calc( a, b );%@AE@%%@NL@%
  13262. %@NL@%
  13263. pushes %@AS@% b %@AE@% onto the stack before it pushes %@AS@% a%@AE@%. In contrast with the other
  13264. high-level languages, the C calling convention specifies that a calling
  13265. routine always adjusts the stack immediately after the called routine
  13266. returns control.  %@NL@%
  13267. %@NL@%
  13268. The BASIC, FORTRAN, and Pascal conventions produce slightly less object
  13269. code. However, the C convention makes calling with a variable number of
  13270. parameters possible. (Because the first parameter is always the last one
  13271. pushed, it is always on the top of the stack; therefore it has the same
  13272. address relative to the frame pointer, regardless of how many parameters
  13273. were actually passed.)  %@NL@%
  13274. %@NL@%
  13275. ────────────────────────────────────────────────────────────────────────────%@NL@%
  13276. NOTE
  13277.  
  13278. %@AI@%The %@AB@%_fastcall%@AE@%%@AI@% keyword, which specifies that parameters are to be passed in
  13279. %@AI@%registers, is incompatible with programs written in other languages. Avoid
  13280. %@AI@%using %@AE@%%@AI@%%@AB@%_fastcall%@AE@%%@AE@%%@AI@% or the /Gr command-line option for C functions that you
  13281. %@AI@%intend to make public to BASIC, FORTRAN, or Pascal programs.%@AE@%%@AE@%%@NL@%
  13282. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  13283. %@NL@%
  13284. %@NL@%
  13285. %@3@%%@CR:C6A00120012 @%%@AB@%12.2.3  Parameter-Passing Requirement%@AE@%%@EH@%%@NL@%
  13286. %@NL@%
  13287. Your programs must agree on the calling convention and the naming
  13288. convention; they must also agree on the order in which they pass parameters.
  13289. It is important that your routines send parameters in the same way to ensure
  13290. proper data transmission and correct program results.%@CR:C6A00120013 @%  %@NL@%
  13291. %@NL@%
  13292. Microsoft compilers support three methods for passing a parameter:  %@NL@%
  13293. %@NL@%
  13294. %@AB@%Method%@AE@%                            %@AB@%Description%@AE@%
  13295. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13296. Near reference                    Passes a variable's near (offset) 
  13297.                                   address. This address is expressed as an
  13298.                                   offset from the default data segment.
  13299.  
  13300.                                   This method gives the called routine 
  13301.                                   direct access to the variable itself. 
  13302.                                   Any change the routine makes to the 
  13303.                                   parameter changes the variable in the 
  13304.                                   calling routine.
  13305.  
  13306. Far reference                     Passes a variable's far (segmented) 
  13307.                                   address.
  13308.  
  13309.                                   This method is similar to passing by 
  13310.                                   near reference, except that a longer 
  13311.                                   address is passed. This method is slower
  13312.                                   than passing by near reference, but is 
  13313.                                   necessary when you pass data that is 
  13314.                                   outside the default data segment. (This 
  13315.                                   is an issue in BASIC or Pascal only if 
  13316.                                   you have specifically requested far 
  13317.                                   memory.)
  13318.  
  13319. Value                             Passes only the variable's value, not 
  13320.                                   its address. 
  13321.  
  13322.                                   With this method, the called routine 
  13323.                                   knows the value of the parameter but has
  13324.                                   no access to the original variable. 
  13325.                                   Changes to a value passed by a parameter
  13326.                                   have no affect on the value of the 
  13327.                                   parameter in the calling routine.
  13328.  
  13329. These different parameter-passing methods mean that you must consider the
  13330. following when programming with mixed languages:  %@NL@%
  13331. %@NL@%
  13332. %@NL@%
  13333.   ■   You need to make sure that the called routine and the calling routine
  13334.       use the same method for passing each parameter (argument). In most
  13335.       cases, you will need to check the parameter-passing defaults used by
  13336.       each language and possibly make adjustments. Each language has
  13337.       keywords or language features that allow you to change
  13338.       parameter-passing methods.%@NL@%
  13339. %@NL@%
  13340.   ■   You may want to choose a specific parameter-passing method rather than
  13341.       using the defaults of any language.%@NL@%
  13342. %@NL@%
  13343. %@NL@%
  13344. Table 12.2 summarizes the parameter-passing defaults for each language.  %@NL@%
  13345. %@NL@%
  13346. %@AB@%Table 12.2  %@AB@%Parameter-Passing Defaults%@AE@%%@AE@%
  13347.  
  13348. %@TH:  13   662 02 10 22 22 22 @%
  13349. Language  Near Reference        Far Reference         By Value
  13350. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13351. BASIC     All                   ---                   ---
  13352.  
  13353. C         Near arrays           Far arrays            All data except
  13354.                                                       arrays
  13355.  
  13356. FORTRAN   All (medium model)    All (large model)     With attributes%@AU@%(1)%@AE@%
  13357.  
  13358. Pascal    %@AB@%VAR, CONST%@AE@%            %@AB@%VARS, CONSTS%@AE@%          Other parameters 
  13359.  
  13360. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13361.  
  13362. %@TE:  13   662 02 10 22 22 22 @%
  13363.  
  13364. %@AU@%(1) %@AE@% When a PASCAL or C attribute is applied to a FORTRAN routine, passing
  13365. by value becomes the  default. %@NL@%
  13366. %@NL@%
  13367. %@NL@%
  13368. %@NL@%
  13369. %@2@%%@CR:C6A00120014 @%%@AB@%12.3  Compiling and Linking%@AE@%%@EH@%%@NL@%
  13370. %@NL@%
  13371. After you have written your source files and decided on a naming convention,
  13372. a calling convention, and a parameter-passing convention, you are ready to
  13373. compile and link individual modules.%@CR:C6A00120015 @%%@CR:C6A00120016 @%%@CR:C6A00120017 @%  %@NL@%
  13374. %@NL@%
  13375. %@NL@%
  13376. %@3@%%@CR:C6A00120018 @%%@AB@%12.3.1  Compiling with Correct Memory Models%@AE@%%@EH@%%@NL@%
  13377. %@NL@%
  13378. With BASIC, FORTRAN, and Pascal, no special options are required to compile
  13379. source files that are part of a mixed-language program.  %@NL@%
  13380. %@NL@%
  13381. %@AU@% With C, not all memory models are compatible with other languages. %@AE@%  %@NL@%
  13382. %@NL@%
  13383. BASIC, FORTRAN, and Pascal use only far (segmented) code addresses.
  13384. Therefore, you must use one of two techniques with C programs that call one
  13385. of these languages: compile C modules in medium, large, or huge model (using
  13386. the /A%@AI@%X%@AE@% command-line options), because these models also use far code
  13387. addresses; or apply the %@AB@%_far%@AE@% keyword to the definitions of C functions you
  13388. make public. If you use the /A%@AI@%X%@AE@% command-line option to specify medium,
  13389. large, or huge model, all your function calls become far by default. This
  13390. means you don't have to declare your functions explicitly with the %@AB@%_far%@AE@%
  13391. keyword.  %@NL@%
  13392. %@NL@%
  13393. Choice of memory model affects the default data pointer size in C and
  13394. FORTRAN, although this default can be overridden with the %@AB@%_near%@AE@% and %@AB@%_far%@AE@%
  13395. keywords. With C and FORTRAN, choice of memory model also affects whether
  13396. data objects are located in the default data segment; if a data object is
  13397. not located in the default data segment, it cannot be passed by near
  13398. reference.  %@NL@%
  13399. %@NL@%
  13400. For more information about code and data address sizes in C, refer to
  13401. Chapter 2, "Managing Memory."  %@NL@%
  13402. %@NL@%
  13403. %@NL@%
  13404. %@3@%%@CR:C6A00120019 @%%@AB@%12.3.2  Linking with Language Libraries%@AE@%%@EH@%%@NL@%
  13405. %@NL@%
  13406. In most cases, you can easily link modules compiled with different
  13407. languages. Do any of the following to ensure that all required libraries
  13408. link in the correct order:  %@NL@%
  13409. %@NL@%
  13410. %@NL@%
  13411.   ■   Put all language libraries in the same directory as the source files.%@NL@%
  13412. %@NL@%
  13413.   ■   List directories containing all needed libraries in the LIB
  13414.       environment variable.%@NL@%
  13415. %@NL@%
  13416.   ■   Let the linker prompt you for libraries.%@NL@%
  13417. %@NL@%
  13418. %@NL@%
  13419. In each of the cases above, the linker finds libraries in the order that it
  13420. requires them. If you enter the library names on the command line, make sure
  13421. you enter them in an order that allows the linker to resolve your program's
  13422. external references. Here are some points to observe when specifying
  13423. libraries on the command line:  %@NL@%
  13424. %@NL@%
  13425. %@NL@%
  13426.   ■   If you are using FORTRAN to write one of your modules, you need to
  13427.       link with the /NOD (no default libraries) option and explicitly
  13428.       specify all the libraries you need on the link command line. You can
  13429.       also specify these libraries with an automatic-response file (or batch
  13430.       file), but you cannot use a default-library search.%@NL@%
  13431. %@NL@%
  13432.   ■   If your program uses both FORTRAN and C, specify the library for the
  13433.       most recent of the two language products first. In addition, make sure
  13434.       that you choose a C-compatible library when you install FORTRAN.%@NL@%
  13435. %@NL@%
  13436.   ■   If you are listing BASIC libraries on the LINK command line, specify
  13437.       those libraries first.%@NL@%
  13438. %@NL@%
  13439. %@NL@%
  13440. The following example shows how to link two modules, %@AS@% mod1 %@AE@% and %@AS@% mod2%@AE@%, with
  13441. a user library, GRAFX, the C run-time library, LLIBCE, and the FORTRAN
  13442. run-time library, LLIBFORE:  %@NL@%
  13443. %@NL@%
  13444. %@AS@%  LINK /NOD mod1 mod2,,,GRAFX+LLIBCE+LLIBFORE%@AE@%%@NL@%
  13445. %@NL@%
  13446. %@NL@%
  13447. %@2@%%@CR:C6A00120020 @%%@AB@%12.4  C Calls to High-Level Languages%@AE@%%@EH@%%@NL@%
  13448. %@NL@%
  13449. Just as you can call Microsoft C routines from other Microsoft languages,
  13450. you can call routines written in Microsoft FORTRAN and Pascal from C. With
  13451. FORTRAN, Pascal, and C, freestanding routines can be written with no
  13452. restriction. When calling BASIC routines, however, you must write the main
  13453. program in BASIC; any subprograms are free to call one another, whether they
  13454. are written in C or BASIC.  %@NL@%
  13455. %@NL@%
  13456. For information about how to pass particular kinds of data, see Section
  13457. 12.9, "Handling Data in Mixed-Language Programming."  %@NL@%
  13458. %@NL@%
  13459. %@NL@%
  13460. %@4@%%@AB@%Executing a Mixed-Language Call%@AE@%%@EH@%%@NL@%
  13461. %@NL@%
  13462. The C interface to other languages uses standard C prototypes, with the
  13463. %@AB@%_fortran%@AE@% or %@AB@%_pascal%@AE@% keyword. Using either of these keywords causes the
  13464. routine to be called with the FORTRAN/Pascal naming and calling convention.
  13465. (The FORTRAN/Pascal convention also works for BASIC.) Here are the
  13466. recommended steps for executing a mixed-language call from C:  %@NL@%
  13467. %@NL@%
  13468. %@NL@%
  13469.   1.  Write a prototype for each mixed-language routine called. The
  13470.       prototype should declare the routine %@AB@%extern%@AE@% for the purpose of program
  13471.       documentation.%@NL@%
  13472. %@NL@%
  13473. %@STUB@%      Instead of using the %@AB@%_fortran%@AE@% or %@AB@%_pascal%@AE@% keyword, you can simply
  13474.       compile with the Pascal calling convention option (/Gc). The /Gc
  13475.       option causes all functions in the module to use the FORTRAN/Pascal
  13476.       naming and calling conventions, except where you apply the %@AB@%_cdecl%@AE@%
  13477.       keyword.%@NL@%
  13478. %@NL@%
  13479.   2.  Pass the values of variables or pointers to variables. You can obtain
  13480.       a pointer to a variable with the address-of (%@AB@%&%@AE@%) operator.%@NL@%
  13481. %@NL@%
  13482. %@STUB@%      In C, array names are always passed as pointers to the first element
  13483.       of the array; they are always passed by reference.%@NL@%
  13484. %@NL@%
  13485. %@STUB@%      The prototype you declare for your function ensures that you are
  13486.       passing the correct length address (that is, near or far). %@NL@%
  13487. %@NL@%
  13488.   3.  Issue a function call in your program as though you were calling a C
  13489.       function.%@NL@%
  13490. %@NL@%
  13491.   4.  Always compile the C module in either medium, large, or huge model, or
  13492.       use the %@AB@%_far %@AE@%keyword in your function prototype. This ensures that a
  13493.       far (intersegment) call is made to the routine. %@NL@%
  13494. %@NL@%
  13495. %@NL@%
  13496. %@NL@%
  13497. %@4@%%@AB@%Using the _fortran or _pascal Keyword%@AE@%%@EH@%%@NL@%
  13498. %@NL@%
  13499. There are two rules of syntax that apply when you use the %@AB@%_fortran%@AE@% or
  13500. %@AB@%_pascal%@AE@% keyword:%@CR:C6A00120021 @%%@CR:C6A00120022 @%  %@NL@%
  13501. %@NL@%
  13502. %@NL@%
  13503.   1.  The %@AB@%_fortran%@AE@% and %@AB@%_pascal%@AE@% keywords modify only the item immediately to
  13504.       their right.%@NL@%
  13505. %@NL@%
  13506.   2.  The %@AB@%_near%@AE@% and %@AB@%_far%@AE@% keywords can be used with the %@AB@%_fortran%@AE@% and %@AB@%_pascal%@AE@%
  13507.       keywords in prototypes. The sequences %@AB@%_fortran _far%@AE@% and %@AB@%_far _fortran%@AE@%
  13508.       are equivalent.%@NL@%
  13509. %@NL@%
  13510. %@NL@%
  13511. The keywords %@AB@%_pascal%@AE@% and %@AB@%_fortran%@AE@% have the same effect on the program; using
  13512. one or the other makes no difference except for internal program
  13513. documentation. Use %@AB@%_fortran%@AE@% to declare a FORTRAN routine, %@AB@%_pascal%@AE@% to declare
  13514. a Pascal rou-tine, and either keyword to declare a BASIC routine.  %@NL@%
  13515. %@NL@%
  13516. The following examples demonstrate the syntax rules presented above.  %@NL@%
  13517. %@NL@%
  13518. The example below declares %@AB@%func%@AE@% to be a BASIC, Pascal, or FORTRAN function
  13519. taking two %@AB@%short%@AE@% parameters and returning a %@AB@%short%@AE@% value.  %@NL@%
  13520. %@NL@%
  13521. %@AS@%  short _pascal func( short sarg1, short sarg2 );%@AE@%%@NL@%
  13522. %@NL@%
  13523. The example below declares %@AB@%func%@AE@% to be pointer to a BASIC, Pascal, or FORTRAN
  13524. routine that takes a %@AB@%long%@AE@% parameter and returns no value. The keyword %@AB@%void%@AE@%
  13525. is appropriate when the called routine is a BASIC subprogram, Pascal
  13526. procedure, or FORTRAN subroutine, since it indicates that the function
  13527. returns no value.  %@NL@%
  13528. %@NL@%
  13529. %@AS@%  void ( _fortran * func )( long larg );%@AE@%%@NL@%
  13530. %@NL@%
  13531. The example below declares %@AB@%func%@AE@% to be a %@AB@%_near%@AE@% BASIC, Pascal, or FORTRAN
  13532. routine. The routine receives a %@AB@%double%@AE@% parameter by reference (because it
  13533. expects a pointer to a %@AB@%double%@AE@%) and returns a %@AB@%short%@AE@% value.  %@NL@%
  13534. %@NL@%
  13535. %@AS@%  short _near _pascal func( _near double * darg );%@AE@%%@NL@%
  13536. %@NL@%
  13537. The example below is equivalent to the preceding example (%@AB@% _pascal _near%@AE@% is
  13538. equivalent to %@AB@%_near _pascal%@AE@%).  %@NL@%
  13539. %@NL@%
  13540. %@AS@%  short _pascal _near func( _near double * darg );%@AE@%%@NL@%
  13541. %@NL@%
  13542. %@AU@% You can make C adopt the conventions of other languages.%@AE@%  %@NL@%
  13543. %@NL@%
  13544. When you call a BASIC subprogram, you must use the FORTRAN/Pascal
  13545. conventions to make the call. When you call FORTRAN or Pascal, however, you
  13546. have a choice. You can make C adopt the conventions described in the
  13547. previous section, or you can make the FORTRAN or Pascal routine adopt the C
  13548. conventions.  %@NL@%
  13549. %@NL@%
  13550. To make a FORTRAN or Pascal routine adopt the C conventions, put the %@AB@%C%@AE@%
  13551. attribute in the heading of the routine's definition. The following example
  13552. shows the syntax for the %@AB@%C%@AE@% attribute in a FORTRAN subroutine-definition
  13553. heading:  %@NL@%
  13554. %@NL@%
  13555. %@AS@%  SUBROUTINE FFROMC [C] (N)
  13556. %@AS@%  INTEGER*2 N%@AE@%%@NL@%
  13557. %@NL@%
  13558. The following example shows the syntax for the %@AB@%C%@AE@% attribute in a Pascal
  13559. procedure-definition heading:  %@NL@%
  13560. %@NL@%
  13561. %@AS@%  PROCEDURE Pfromc( n : INTEGER ) [C];%@AE@%%@NL@%
  13562. %@NL@%
  13563. To make a C function adopt the FORTRAN/Pascal conventions, declare the
  13564. function as %@AB@%_fortran%@AE@% or %@AB@%_pascal%@AE@%. For example,  %@NL@%
  13565. %@NL@%
  13566. %@AS@%  void _pascal CfromP( int n );%@AE@%%@NL@%
  13567. %@NL@%
  13568. %@NL@%
  13569. %@2@%%@CR:C6A00120023 @%%@AB@%12.5  C Calls to BASIC%@AE@%%@EH@%%@NL@%
  13570. %@NL@%
  13571. No BASIC routine can be executed unless the main program is in BASIC,
  13572. because a BASIC routine requires the environment to be initialized in a way
  13573. that is unique to BASIC. No other language will perform this special
  13574. initialization.  %@NL@%
  13575. %@NL@%
  13576. However, your program can start up in BASIC, call a C function that does
  13577. most of the work of the program, and then call BASIC subprograms and
  13578. function procedures as needed. Figure 12.3 illustrates how to do this.  %@NL@%
  13579. %@NL@%
  13580. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  13581. %@NL@%
  13582. Follow these rules when you call BASIC from C:  %@NL@%
  13583. %@NL@%
  13584. %@NL@%
  13585.   1.  Start up in a BASIC main module. You will need to use the %@AB@%DECLARE%@AE@%
  13586.       statement to provide an interface to the C module. %@NL@%
  13587. %@NL@%
  13588.   2.  In the C module, write a prototype for the BASIC routine and include
  13589.       type information for parameters. Use either the %@AB@%_fortran%@AE@% or %@AB@%_pascal%@AE@%
  13590.       keyword to modify the routine itself.%@NL@%
  13591. %@NL@%
  13592.   3.  Make sure that all data are passed as near pointers. BASIC can pass
  13593.       data in a variety of ways but is unable to receive data in any form
  13594.       other than near reference. With near pointers, the program assumes
  13595.       that the data are in the default data segment. If you want to pass
  13596.       data that are not in the default data segment, copy the data to a
  13597.       variable in the default data segment.%@NL@%
  13598. %@NL@%
  13599.   4.  Compile the C module in medium or large model to ensure far
  13600.       (intersegment) calls.%@NL@%
  13601. %@NL@%
  13602. %@NL@%
  13603. The example below demonstrates a BASIC program that calls a C function. The
  13604. C function then calls a BASIC function that returns twice the number passed
  13605. to it and a BASIC subprogram that prints two numbers.  %@NL@%
  13606. %@NL@%
  13607. %@AS@%  ' BASIC source
  13608. %@AS@%  '
  13609. %@AS@%  ' The main program is in BASIC because of BASIC's start-up
  13610. %@AS@%  ' requirements.  The BASIC main program calls the C function
  13611. %@AS@%  ' Cprog.
  13612. %@AS@%  '
  13613. %@AS@%  ' Cprog calls the BASIC subroutine Dbl.
  13614. %@AS@%  '
  13615. %@AS@%  DEFINT A-Z
  13616. %@AS@%  DECLARE SUB Cprog CDECL()
  13617. %@AS@%  CALL Cprog
  13618. %@AS@%  END
  13619. %@AS@%  '
  13620. %@AS@%  FUNCTION Dbl(N) STATIC
  13621. %@AS@%      Dbl = N*2
  13622. %@AS@%  END FUNCTION
  13623. %@AS@%  '
  13624. %@AS@%  SUB Printnum(A,B) STATIC
  13625. %@AS@%      PRINT "The first number is ";A
  13626. %@AS@%      PRINT "The second number is ";B
  13627. %@AS@%  END SUB
  13628. %@AS@%  
  13629. %@AS@%  
  13630. %@AS@%  /* C source; compile in medium or large model */
  13631. %@AS@%  
  13632. %@AS@%  int _fortran dbl( int _near * N );
  13633. %@AS@%  void _fortran printnum( int _near * A, int _near * B );
  13634. %@AS@%  
  13635. %@AS@%  void cprog()
  13636. %@AS@%  {
  13637. %@AS@%  int a = 5;
  13638. %@AS@%  int b = 6;
  13639. %@AS@%  
  13640. %@AS@%      printf( "%d times 2 is %d\n", a, dbl( &a ) );
  13641. %@AS@%      printnum( &a, &b );
  13642. %@AS@%  }%@AE@%%@NL@%
  13643. %@NL@%
  13644. In the previous example, note that the addresses of %@AS@% a %@AE@% and %@AS@% b %@AE@% are passed,
  13645. since BASIC expects to receive addresses for parameters. This is important
  13646. because C passes parameters by value unless you use the address-of (%@AB@%&%@AE@%)
  13647. operator to obtain the address, or are passing an array. Also note that the
  13648. function prototype for %@AS@% printnum %@AE@% declares the parameters as near pointers.
  13649. The prototype causes the  %@NL@%
  13650. %@NL@%
  13651. variables to be passed by near reference. If %@AS@% a %@AE@% or %@AS@% b %@AE@% is declared as %@AB@%_far%@AE@%,
  13652. the C compiler issues a warning that you are converting a far pointer to a
  13653. near pointer and that a segment was lost in the conversion.  %@NL@%
  13654. %@NL@%
  13655. Calling and naming conventions are resolved by the %@AB@%CDECL%@AE@% keyword in the
  13656. BASIC declaration of %@AB@%Cprog%@AE@%, and by the %@AB@%_fortran%@AE@% keyword in the C declaration
  13657. of %@AS@% dbl %@AE@% and %@AS@% printnum%@AE@%.  %@NL@%
  13658. %@NL@%
  13659. %@AU@% BASIC can invoke one of your functions as part of the termination
  13660. %@AU@%procedure.%@AE@%  %@NL@%
  13661. %@NL@%
  13662. Versions of QuickBASIC later than 4.0 provide a "user entry point,"
  13663. %@AB@%B_OnExit%@AE@%, which can be called directly from C. The %@AB@%B_OnExit%@AE@% function enables
  13664. you to make sure you have performed an orderly termination. The following
  13665. code shows how to use %@AB@%B_OnExit%@AE@%.  %@NL@%
  13666. %@NL@%
  13667. %@AS@%  #include <malloc.h>    /* For declaration of _fmalloc */
  13668. %@AS@%  #include <stdlib.h>    /* For declaration of onexit_t */
  13669. %@AS@%  
  13670. %@AS@%  /* The prototype for B_OnExit declares it as a function
  13671. %@AS@%   * returning type onexit_t that takes one parameter. The
  13672. %@AS@%   * parameter is a far pointer to a function that returns
  13673. %@AS@%   * no value.
  13674. %@AS@%   */
  13675. %@AS@%  extern onexit_t _pascal _far B_OnExit( onexit_t );
  13676. %@AS@%  void TermProc( void );
  13677. %@AS@%  
  13678. %@AS@%  int * p_IntArray;
  13679. %@AS@%  
  13680. %@AS@%  void InitProc( void )
  13681. %@AS@%  {
  13682. %@AS@%      /* Allocate far space for 20-integer array */
  13683. %@AS@%  
  13684. %@AS@%      p_IntArray = (int *)_fmalloc( 20 * sizeof( int ) );
  13685. %@AS@%  
  13686. %@AS@%      /* Log termination routine (TermProc) with BASIC. */
  13687. %@AS@%  
  13688. %@AS@%      B_OnExit( TermProc );
  13689. %@AS@%  }
  13690. %@AS@%  
  13691. %@AS@%  void TermProc( void )
  13692. %@AS@%  {
  13693. %@AS@%      free( p_IntArray );    /* Release far space allocated */
  13694. %@AS@%  }                          /* previously by InitProc.     */%@AE@%%@NL@%
  13695. %@NL@%
  13696. %@NL@%
  13697. %@2@%%@CR:C6A00120024 @%%@AB@%12.6  C Calls to FORTRAN%@AE@%%@EH@%%@NL@%
  13698. %@NL@%
  13699. This section shows two examples of C-FORTRAN programs. There are two types
  13700. of subprogram calls to FORTRAN routines: calls to subroutines and calls to
  13701. functions. Functions return a value, while subroutines do not. The examples
  13702. in the next sections illustrate how to handle the difference between
  13703. function and subroutine calls.  %@NL@%
  13704. %@NL@%
  13705. %@NL@%
  13706. %@3@%%@CR:C6A00120025 @%%@AB@%12.6.1  Calling a FORTRAN Subroutine from C%@AE@%%@EH@%%@NL@%
  13707. %@NL@%
  13708. The example below demonstrates a C main module calling a FORTRAN subroutine,
  13709. %@AB@%MAXPARAM%@AE@%. This subroutine adjusts the lower of two arguments to be equal to
  13710. the higher argument.  %@NL@%
  13711. %@NL@%
  13712. %@AS@%  /* C source file - calls FORTRAN subroutine
  13713. %@AS@%   * Compile in medium or large model
  13714. %@AS@%   */
  13715. %@AS@%  
  13716. %@AS@%  extern void _fortran maxparam( int _near * I, int _near * J );
  13717. %@AS@%  
  13718. %@AS@%  /* Declare as void, because there is no return value.
  13719. %@AS@%   * FORTRAN keyword causes C to use FORTRAN/Pascal
  13720. %@AS@%   * calling and naming conventions.
  13721. %@AS@%   * Two integer parameters, passed by near reference.
  13722. %@AS@%   */
  13723. %@AS@%  
  13724. %@AS@%  main()
  13725. %@AS@%  {
  13726. %@AS@%      int a = 5;
  13727. %@AS@%      int b = 7;
  13728. %@AS@%  
  13729. %@AS@%      printf( "a = %d, b = %d", a, b );
  13730. %@AS@%      maxparam( &a, &b );
  13731. %@AS@%      printf( "a = %d, b = %d", a, b );
  13732. %@AS@%  }
  13733. %@AS@%  
  13734. %@AS@%  C   FORTRAN source file, subroutine MAXPARAM
  13735. %@AS@%  C
  13736. %@AS@%  $NOTRUNCATE
  13737. %@AS@%  
  13738. %@AS@%      SUBROUTINE MAXPARAM (I, J)
  13739. %@AS@%      INTEGER*2 I [NEAR]
  13740. %@AS@%      INTEGER*2 J [NEAR]
  13741. %@AS@%  C
  13742. %@AS@%  C   I and J received by near reference,
  13743. %@AS@%  C   because of NEAR attribute
  13744. %@AS@%  C
  13745. %@AS@%      IF (I .GT. J) THEN
  13746. %@AS@%          J = I
  13747. %@AS@%      ELSE
  13748. %@AS@%          I = J
  13749. %@AS@%      ENDIF
  13750. %@AS@%      END%@AE@%%@NL@%
  13751. %@NL@%
  13752. In the previous example, the C program adopts the naming convention and
  13753. call-ing convention of the FORTRAN subroutine. The two programs must agree
  13754. on whether parameters are to be passed by reference or by value. The
  13755. following keywords affect how the two programs interface:  %@NL@%
  13756. %@NL@%
  13757. %@NL@%
  13758.   ■   The %@AB@%_fortran%@AE@% keyword directs C to call %@AS@% maxparam %@AE@% with the FORTRAN/
  13759.       Pascal naming convention (as %@AS@% MAXPARAM%@AE@%);%@AB@% _fortran%@AE@% also directs C to
  13760.       call %@AS@% maxparam %@AE@% with the FORTRAN/Pascal calling convention.%@NL@%
  13761. %@NL@%
  13762.   ■   Since the FORTRAN subroutine %@AS@% MAXPARAM %@AE@% may alter the value of either
  13763.       parameter, both parameters must be passed by reference. In this case,
  13764.       near reference was chosen; this method is specified in C by the use of
  13765.       near pointers, and in FORTRAN by applying the %@AB@%NEAR%@AE@% keyword to the
  13766.       parameter declarations.%@NL@%
  13767. %@NL@%
  13768. %@STUB@%      Far reference could have been specified by using far pointers in C. In
  13769.       that case, you would not declare the FORTRAN subroutine %@AS@% MAXPARAM %@AE@%
  13770.       with the %@AB@%NEAR%@AE@% keyword. If you compile the FORTRAN program in medium
  13771.       model, declare %@AS@% MAXPARAM %@AE@% using the %@AB@%FAR%@AE@% keyword.%@NL@%
  13772. %@NL@%
  13773. %@NL@%
  13774. %@NL@%
  13775. %@3@%%@CR:C6A00120026 @%%@AB@%12.6.2  Calling a FORTRAN Function from C%@AE@%%@EH@%%@NL@%
  13776. %@NL@%
  13777. The example below demonstrates a C main module calling the FORTRAN  function
  13778. %@AS@% fact%@AE@%. This function returns the factorial of an integer value.  %@NL@%
  13779. %@NL@%
  13780. %@AS@%  /* C source file - calls FORTRAN function.
  13781. %@AS@%   * Compile in medium or large model.
  13782. %@AS@%   */
  13783. %@AS@%  
  13784. %@AS@%  int _fortran fact( int N );
  13785. %@AS@%  
  13786. %@AS@%  /* FORTRAN keyword causes C to use FORTRAN/Pascal
  13787. %@AS@%   * calling and naming conventions.
  13788. %@AS@%   * Integer parameter passed by value.
  13789. %@AS@%   */
  13790. %@AS@%  
  13791. %@AS@%  main()
  13792. %@AS@%  {
  13793. %@AS@%   int x = 3;
  13794. %@AS@%   int y = 4;
  13795. %@AS@%  
  13796. %@AS@%      printf( "The factorial of x   is %4d", fact( x ) );
  13797. %@AS@%      printf( "The factorial of y   is %4d", fact( y ) );
  13798. %@AS@%      printf( "The factorial of x+y is %4d", fact( x + y ) );
  13799. %@AS@%  }%@AE@%%@NL@%
  13800. %@NL@%
  13801. %@AS@%  C   FORTRAN source file - factorial function
  13802. %@AS@%  C
  13803. %@AS@%  $NOTRUNCATE
  13804. %@AS@%      INTEGER*2 FUNCTION FACT (N)
  13805. %@AS@%      INTEGER*2 N [VALUE]
  13806. %@AS@%  C
  13807. %@AS@%  C   N is received by value, because of VALUE attribute
  13808. %@AS@%  C
  13809. %@AS@%         INTEGER*2 I
  13810. %@AS@%         FACT = 1
  13811. %@AS@%         DO 100 I = 1, N
  13812. %@AS@%             FACT = FACT * I
  13813. %@AS@%  100    CONTINUE
  13814. %@AS@%         RETURN
  13815. %@AS@%         END%@AE@%%@NL@%
  13816. %@NL@%
  13817. In the example above, the C program adopts the naming convention and calling
  13818. convention of the FORTRAN subroutine. Both programs must agree on whether
  13819. parameters are passed by reference or by value. Note that the C program
  13820. passes the parameters by value rather than by reference. Passing parameters
  13821. by value is the default for C. To accept parameters passed by value, the
  13822. keyword %@AB@%VALUE%@AE@% is used in the declaration of %@AS@% N %@AE@% in the FORTRAN function. The
  13823. %@AB@%_fortran%@AE@% keyword directs C to call %@AS@% fact %@AE@% with the FORTRAN/Pascal naming
  13824. convention (as %@AS@% FACT%@AE@%); %@AB@%_fortran%@AE@% also directs C to call %@AS@% fact %@AE@% with the
  13825. FORTRAN/Pascal calling convention.  %@NL@%
  13826. %@NL@%
  13827. When passing a parameter that should not be changed, pass the parameter by
  13828. value. Passing by value is the default method in C and is specified in
  13829. FORTRAN by applying the %@AB@%VALUE%@AE@% attribute to the parameter declaration.  %@NL@%
  13830. %@NL@%
  13831. %@NL@%
  13832. %@2@%%@CR:C6A00120027 @%%@AB@%12.7  C Calls to Pascal%@AE@%%@EH@%%@NL@%
  13833. %@NL@%
  13834. This section shows two examples of C-Pascal programs. There are two types of
  13835. subprogram calls to Pascal routines: calls to procedures and calls to
  13836. functions. Functions return a value, while procedures do not. The examples
  13837. in the next sections illustrate how to handle the difference between
  13838. function and procedure calls.  %@NL@%
  13839. %@NL@%
  13840. %@NL@%
  13841. %@3@%%@CR:C6A00120028 @%%@AB@%12.7.1  Calling a Pascal Procedure from C%@AE@%%@EH@%%@NL@%
  13842. %@NL@%
  13843. The following example demonstrates a C main module calling a Pascal
  13844. procedure, %@AS@% maxparam%@AE@%. This procedure adjusts the lower of two arguments to
  13845. be equal to the higher argument.  %@NL@%
  13846. %@NL@%
  13847. %@AS@%  /* C source file - calls Pascal procedure.
  13848. %@AS@%   * Compile in medium or large model.
  13849. %@AS@%   */
  13850. %@AS@%  
  13851. %@AS@%  void _pascal maxparam( int _near * a, int _near * b );
  13852. %@AS@%  
  13853. %@AS@%  /* Declare as void, because there is no return value.
  13854. %@AS@%   * The _pascal keyword causes C to use FORTRAN/Pascal
  13855. %@AS@%   * calling and naming conventions.
  13856. %@AS@%   * Two integer params, passed by near reference.
  13857. %@AS@%   */
  13858. %@AS@%  
  13859. %@AS@%  main()
  13860. %@AS@%  {
  13861. %@AS@%      int a = 5;
  13862. %@AS@%      int b = 7;
  13863. %@AS@%  
  13864. %@AS@%      printf( "a = %d, b = %d", a, b );
  13865. %@AS@%      maxparam( &a, &b );
  13866. %@AS@%      printf( "a = %d, b = %d", a, b );
  13867. %@AS@%  }
  13868. %@AS@%  
  13869. %@AS@%  { Pascal source code - Maxparam procedure. }
  13870. %@AS@%  
  13871. %@AS@%  MODULE Psub;
  13872. %@AS@%  PROCEDURE Maxparam( VAR a:INTEGER; VAR b:INTEGER );
  13873. %@AS@%  
  13874. %@AS@%  { Two integer parameters are received by near reference. }
  13875. %@AS@%  { Near reference is specified with the VAR keyword. }
  13876. %@AS@%  
  13877. %@AS@%      BEGIN
  13878. %@AS@%          if a > b THEN
  13879. %@AS@%              b := a
  13880. %@AS@%          ELSE
  13881. %@AS@%              a := b
  13882. %@AS@%      END;
  13883. %@AS@%  END.%@AE@%%@NL@%
  13884. %@NL@%
  13885. In the example above, the C program adopts the Pascal naming convention and
  13886. calling convention. Both programs must agree on whether parameters are
  13887. passed by reference or by value; the following keywords affect the
  13888. conventions:  %@NL@%
  13889. %@NL@%
  13890. %@NL@%
  13891.   ■   The %@AB@%_pascal%@AE@% keyword directs C to call %@AS@% Maxparam %@AE@% with the FORTRAN/
  13892.       Pascal naming convention (as %@AS@% MAXPARAM%@AE@%); %@AB@%_pascal%@AE@% also directs C to
  13893.       call %@AS@%Maxparam %@AE@% with the FORTRAN/Pascal calling convention.%@NL@%
  13894. %@NL@%
  13895.   ■   Since the procedure %@AS@% Maxparam %@AE@% can alter the value of either
  13896.       parameter, both parameters must be passed by reference. In this case,
  13897.       near reference is used; this method is specified in C by the use of
  13898.       near pointers, and in Pascal with the %@AB@%VAR%@AE@% keyword.%@NL@%
  13899. %@NL@%
  13900. %@STUB@%      Far reference could have been specified by using far pointers in C. To
  13901.       specify far reference in Pascal, use the %@AB@%VARS%@AE@% keyword instead of %@AB@%VAR%@AE@%.%@NL@%
  13902. %@NL@%
  13903. %@NL@%
  13904. %@NL@%
  13905. %@3@%%@CR:C6A00120029 @%%@AB@%12.7.2  Calling a Pascal Function from C%@AE@%%@EH@%%@NL@%
  13906. %@NL@%
  13907. The example below demonstrates a C main module calling Pascal function %@AS@%
  13908. %@AS@%fact%@AE@%. This function returns the factorial of an integer value.  %@NL@%
  13909. %@NL@%
  13910. %@AS@%  /* C source file - calls Pascal function.
  13911. %@AS@%   * Compile in medium or large model.
  13912. %@AS@%   */
  13913. %@AS@%  
  13914. %@AS@%  int _pascal fact(int n);
  13915. %@AS@%  
  13916. %@AS@%  /* PASCAL keyword causes C to use FORTRAN/Pascal
  13917. %@AS@%   * calling and naming conventions.
  13918. %@AS@%   * Integer parameter passed by value.
  13919. %@AS@%   */
  13920. %@AS@%  
  13921. %@AS@%  main()
  13922. %@AS@%  {
  13923. %@AS@%      int x = 3;
  13924. %@AS@%      int y = 4;
  13925. %@AS@%  
  13926. %@AS@%      printf( "The factorial of x   is %4d", fact( x ) );
  13927. %@AS@%      printf( "The factorial of y   is %4d", fact( y ) );
  13928. %@AS@%      printf( "The factorial of x+y is %4d", fact( x + y ) );
  13929. %@AS@%  }
  13930. %@AS@%  
  13931. %@AS@%  { Pascal source code - factorial function. }
  13932. %@AS@%  
  13933. %@AS@%  MODULE Pfun;
  13934. %@AS@%  FUNCTION Fact (n : INTEGER) : INTEGER;
  13935. %@AS@%  
  13936. %@AS@%  {Integer parameters received by value, the Pascal default. }
  13937. %@AS@%  
  13938. %@AS@%      BEGIN
  13939. %@AS@%          Fact := 1;
  13940. %@AS@%          WHILE n > 0 DO
  13941. %@AS@%              BEGIN
  13942. %@AS@%                  Fact := Fact * n;
  13943. %@AS@%                  n := n - 1;          {Parameter n modified.}
  13944. %@AS@%              END;
  13945. %@AS@%      END;
  13946. %@AS@%  END.%@AE@%%@NL@%
  13947. %@NL@%
  13948. In the example above, the C program adopts the Pascal naming convention and
  13949. calling convention. Both programs must agree on whether parameters are
  13950. passed by reference or by value. The %@AB@%_pascal%@AE@% keyword directs C to call %@AS@% fact
  13951. %@AS@%%@AE@% with the FORTRAN/Pascal naming convention (as %@AS@% FACT%@AE@%); %@AB@% _pascal%@AE@% also directs
  13952. C to call %@AS@%fact %@AE@% with the FORTRAN/Pascal calling convention.  %@NL@%
  13953. %@NL@%
  13954. The Pascal function %@AS@% fact %@AE@% should receive a parameter by value. Otherwise,
  13955. the Pascal function will corrupt the parameter's value in the calling
  13956. module. Passing by value is the default method for both C and Pascal.  %@NL@%
  13957. %@NL@%
  13958. %@NL@%
  13959. %@2@%%@CR:C6A00120030 @%%@AB@%12.8  C Calls to Assembly Language%@AE@%%@EH@%%@NL@%
  13960. %@NL@%
  13961. In Microsoft C, Version 6.0, you can write assembly-language programs either
  13962. by using the in-line assembler or by creating a stand-alone module using the
  13963. Microsoft Macro Assembler (MASM). If you use the in-line assembler, you do
  13964. not need to take any special precautions other than those outlined in
  13965. Chapter 3, "Using the In-Line Assembler." This section explains the
  13966. techniques for interfacing your assembly-language routines with your C
  13967. program.  %@NL@%
  13968. %@NL@%
  13969. When deciding whether to use the in-line assembler or MASM, there are
  13970. several considerations. Here is a list of advantages MASM provides over the
  13971. in-line assembler:  %@NL@%
  13972. %@NL@%
  13973. %@NL@%
  13974.   ■   MASM supports declaration of data in MASM format; in-line assembly
  13975.       does not.%@NL@%
  13976. %@NL@%
  13977.   ■   MASM has a more powerful macro capability than in-line assembly.%@NL@%
  13978. %@NL@%
  13979.   ■   Modules written for MASM can be interfaced more easily with modules
  13980.       written in more than one Microsoft high-level language.%@NL@%
  13981. %@NL@%
  13982.   ■   MASM assembles large assembly-language programs more quickly than the
  13983.       in-line assembler.%@NL@%
  13984. %@NL@%
  13985.   ■   MASM supports assembly-language code written prior to the existence of
  13986.       the in-line assembler.%@NL@%
  13987. %@NL@%
  13988.   ■   MASM error messages and warnings are more complete than those of the
  13989.       in-line assembler.%@NL@%
  13990. %@NL@%
  13991. %@NL@%
  13992. The in-line assembler is far more efficient for some assembly-language
  13993. programming tasks. Here are some of the benefits of the in-line assembler:  %@NL@%
  13994. %@NL@%
  13995. %@NL@%
  13996.   ■   You can do spot optimizations by including short sections of
  13997.       assemblylanguage code in your C programs with the in-line assembler.%@NL@%
  13998. %@NL@%
  13999.   ■   Code written in in-line assembler does not necessarily incur the
  14000.       overhead of a function call; code assembled using MASM always does.%@NL@%
  14001. %@NL@%
  14002.   ■   You can include in-line assembly code in your C source files; code
  14003.       written for MASM must be in a separate file.%@NL@%
  14004. %@NL@%
  14005. %@NL@%
  14006. %@NL@%
  14007. %@3@%%@CR:C6A00120031 @%%@AB@%12.8.1  Writing the Assembly-Language Procedure%@AE@%%@EH@%%@NL@%
  14008. %@NL@%
  14009. You must write your assembly-language procedure so that it uses the same
  14010. call-ing conventions and naming conventions as your C program. If you follow
  14011. these conventions, you will be able to write recursive procedures
  14012. (procedures that call themselves), and you will be able to use the CodeView
  14013. debugger to locate errors in the code.  %@NL@%
  14014. %@NL@%
  14015. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14016. NOTE
  14017.  
  14018. %@AI@%This section discusses only the simplified segment directives provided with
  14019. %@AI@%the Microsoft Macro Assembler, version 5.0. If you are using a version prior
  14020. %@AI@%to 5.0, you have to specify complete %@AI@%SEGMENT %@AE@%%@AI@%directives.%@AE@%%@AE@%%@NL@%
  14021. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  14022. %@NL@%
  14023. The standard assembly-language interface method consists of these steps:  %@NL@%
  14024. %@NL@%
  14025. %@NL@%
  14026.   1.  Setting up the procedure%@NL@%
  14027. %@NL@%
  14028.   2.  Entering the procedure%@NL@%
  14029. %@NL@%
  14030.   3.  Allocating local data (optional)%@NL@%
  14031. %@NL@%
  14032.   4.  Preserving register values%@NL@%
  14033. %@NL@%
  14034.   5.  Accessing parameters%@NL@%
  14035. %@NL@%
  14036.   6.  Returning a value (optional)%@NL@%
  14037. %@NL@%
  14038.   7.  Exiting the procedure%@NL@%
  14039. %@NL@%
  14040. %@NL@%
  14041. The next sections describe each of these steps in detail.  %@NL@%
  14042. %@NL@%
  14043. %@NL@%
  14044. %@3@%%@CR:C6A00120032 @%%@AB@%12.8.2  Setting Up the Procedure%@AE@%%@EH@%%@NL@%
  14045. %@NL@%
  14046. The linker cannot combine the assembly-language procedure with the C program
  14047. unless you define compatible segments and declare the procedure properly.
  14048. Perform the following steps to set up the procedure:  %@NL@%
  14049. %@NL@%
  14050. %@NL@%
  14051.   1.  Use the %@AB@%.MODEL%@AE@% directive at the beginning of the source file; this
  14052.       directive automatically causes the appropriate kind of returns to be
  14053.       generated (%@AB@%NEAR%@AE@% for tiny, small or compact models, %@AB@%FAR%@AE@% for medium,
  14054.       large, or huge models).%@NL@%
  14055. %@NL@%
  14056. %@STUB@%      If you are using a version of MASM prior to 5.0, declare the procedure
  14057.       %@AB@%NEAR%@AE@% for small or compact model, %@AB@%FAR%@AE@% for medium, large, or huge
  14058.       models.%@NL@%
  14059. %@NL@%
  14060.   2.  Use the simplified segment directives %@AB@%.CODE%@AE@% and %@AB@%.DATA%@AE@% to declare the
  14061.       code and data segments.%@NL@%
  14062. %@NL@%
  14063. %@STUB@%      If you are using a version of MASM prior to 5.0, declare the segments
  14064.       using the %@AB@%SEGMENT%@AE@%, %@AB@%GROUP%@AE@%, and %@AB@%ASSUME%@AE@% directives. These directives are
  14065.       described in the %@AI@%Microsoft%@AE@% %@AI@%Macro Assembler%@AE@% %@AI@%Reference %@AE@%.%@NL@%
  14066. %@NL@%
  14067.   3.  Use the %@AB@%PUBLIC %@AE@%directive to declare the procedure label public. This
  14068.       declaration makes the procedure visible to other modules. Also declare
  14069.       any data you want to make public as %@AB@%PUBLIC%@AE@%.%@NL@%
  14070. %@NL@%
  14071.   4.  Use the %@AB@%EXTRN %@AE@%directive to declare any global data or procedures
  14072.       accessed by the routine as external. The safest way to use%@AB@% EXTRN%@AE@% is to
  14073.       place the directive outside any segment definition; however, place
  14074.       near data inside the data segment.%@NL@%
  14075. %@NL@%
  14076.   5.  Observe the C naming convention; precede all procedure names and
  14077.       global data names with an underscore.%@NL@%
  14078. %@NL@%
  14079. %@NL@%
  14080. %@NL@%
  14081. %@3@%%@CR:C6A00120033 @%%@AB@%12.8.3  Entering the Procedure%@AE@%%@EH@%%@NL@%
  14082. %@NL@%
  14083. When you enter the procedure, in most cases you will want to set up a "stack
  14084. frame." This allows you to access parameters passed on the stack and to
  14085. allocate local data on the stack. You do not need to set up the stack frame
  14086. if your procedure accepts no arguments and does not use the stack.  %@NL@%
  14087. %@NL@%
  14088. To set up the stack frame, issue the instructions:  %@NL@%
  14089. %@NL@%
  14090. %@AS@%  push    bp
  14091. %@AS@%  mov     bp,sp%@AE@%%@NL@%
  14092. %@NL@%
  14093. This sequence establishes BP as the frame pointer. You cannot use SP for
  14094. this purpose because it is not an index or base register. Also, the value of
  14095. SP may change as more data are pushed onto the stack. However, the value of
  14096. the base register BP remains constant for the life of the procedure unless
  14097. your program changes it, so each parameter can be addressed as an offset
  14098. from BP.  %@NL@%
  14099. %@NL@%
  14100. The instruction sequence above preserves the value of BP, since it will be
  14101. needed in the calling procedure as soon as your assembly-language procedure
  14102. returns. It then transfers the value in SP to BP to establish a stack frame
  14103. on entry to the procedure.  %@NL@%
  14104. %@NL@%
  14105. %@NL@%
  14106. %@3@%%@CR:C6A00120034 @%%@AB@%12.8.4  Allocating Local Data%@AE@%%@EH@%%@NL@%
  14107. %@NL@%
  14108. Your assembly-language procedure can use the same technique for allocating
  14109. temporary storage for local data that is used by high-level languages. To
  14110. set up local data space, decrease the contents of SP just after setting up
  14111. the stack frame. (To ensure correct execution, always increase or decrease
  14112. SP by an even number.) Decreasing SP reserves space on the stack for local
  14113. data. You must restore the space at the end of the procedure as follows:  %@NL@%
  14114. %@NL@%
  14115. %@AS@%  push    bp
  14116. %@AS@%  mov     bp,sp
  14117. %@AS@%  sub     sp,space%@AE@%%@NL@%
  14118. %@NL@%
  14119. In the example above, %@AS@% space %@AE@% is the total size in bytes of the local data
  14120. you want to allocate. Local variables are then accessed as fixed negative
  14121. displacements from BP.  %@NL@%
  14122. %@NL@%
  14123. In the following example, the entry sequence establishes a stack frame and
  14124. allocates temporary local storage for two words (4 bytes) of data. Later in
  14125. the example, the program accesses the local storage, initializing both to 0.
  14126. %@NL@%
  14127. %@NL@%
  14128. %@AS@%  push    bp          ; Save old stack frame.
  14129. %@AS@%  mov     bp,sp       ; Set up new stack frame.
  14130. %@AS@%  sub     sp,4        ; Allocate 4 bytes of local storage.
  14131. %@AS@%  .
  14132. %@AS@%  .
  14133. %@AS@%  .
  14134. %@AS@%  mov     WORD PTR [bp-2],0
  14135. %@AS@%  mov     WORD PTR [bp-4],0%@AE@%%@NL@%
  14136. %@NL@%
  14137. Note that local variables are also called dynamic, stack, or automatic
  14138. variables.  %@NL@%
  14139. %@NL@%
  14140. %@NL@%
  14141. %@3@%%@CR:C6A00120035 @%%@AB@%12.8.5  Preserving Register Values%@AE@%%@EH@%%@NL@%
  14142. %@NL@%
  14143. A procedure called from C should preserve the values of SI, DI, SS, and DS
  14144. (in addition to BP, which is already saved). You should push any register
  14145. value that your procedure modifies onto the stack after setting up the stack
  14146. frame and allocating local storage, but prior to entering the main body of
  14147. the procedure. Registers that your procedure does not alter need not be
  14148. preserved.  %@NL@%
  14149. %@NL@%
  14150. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14151. %@AU@%WARNING%@AE@%%@NL@%
  14152. %@NL@%
  14153. Routines that your assembly-language procedure calls must not alter the SI,
  14154. DI, SS, DS, or BP registers. If they do, and you have not preserved the
  14155. registers, they can corrupt the calling program's register variables,
  14156. segment registers, and stack frame, causing program failure. If your
  14157. procedure modifies the direction flag using the %@AI@%STD%@AE@%%@AB@% %@AE@%or %@AI@%CLD %@AE@%instructions, you
  14158. must preserve the flags register.%@NL@%
  14159. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14160. %@NL@%
  14161. The example below shows an entry sequence that sets up a stack frame,
  14162. allocates 4 bytes of local data space on the stack, then preserves the SI,
  14163. DI, and flags registers.  %@NL@%
  14164. %@NL@%
  14165. %@AS@%  push    bp        ; Save caller's stack frame.
  14166. %@AS@%  mov     bp,sp     ; Establish new stack frame.
  14167. %@AS@%  sub     sp,4      ; Allocate local data space.
  14168. %@AS@%  push    si        ; Save SI and DI registers.
  14169. %@AS@%  push    di
  14170. %@AS@%  pushf             ; Save the flags register.
  14171. %@AS@%  .
  14172. %@AS@%  .
  14173. %@AS@%  .%@AE@%%@NL@%
  14174. %@NL@%
  14175. In the example above, you must exit the procedure with the following code:  %@NL@%
  14176. %@NL@%
  14177. %@AS@%  popf              ; Restore the flags register.
  14178. %@AS@%  pop    di         ; Restore the old value in the DI 
  14179. %@AS@%                      register.
  14180. %@AS@%  pop    si         ; Restore the old value in the SI 
  14181. %@AS@%                      register.
  14182. %@AS@%  mov    sp,bp      ; Restore the stack pointer.
  14183. %@AS@%  pop    bp         ; Restore the frame pointer.
  14184. %@AS@%  ret               ; Return to the calling routine.%@AE@%%@NL@%
  14185. %@NL@%
  14186. If you do not issue the instructions above in the order shown, you will
  14187. place incorrect data in registers. Follow the rules below when restoring the
  14188. calling program's registers, stack pointer, and frame pointer:  %@NL@%
  14189. %@NL@%
  14190. %@NL@%
  14191.   ■   Pop all registers that you preserve in the reverse order from which
  14192.       they were pushed onto the stack. So, in the example above, SI and DI
  14193.       are pushed, and DI and SI are popped.%@NL@%
  14194. %@NL@%
  14195.   ■   Restore the stack pointer by transferring the value of BP into SP
  14196.       before restoring the value of the frame pointer.%@NL@%
  14197. %@NL@%
  14198.   ■   Always restore the frame pointer last.%@NL@%
  14199. %@NL@%
  14200. %@NL@%
  14201. %@NL@%
  14202. %@3@%%@CR:C6A00120036 @%%@AB@%12.8.6  Accessing Parameters%@AE@%%@EH@%%@NL@%
  14203. %@NL@%
  14204. Once you have established the frame pointer, allocated local storage (if
  14205. required), and pushed any registers that need to be preserved, you can write
  14206. the main body of the procedure. Figure 12.4 shows how functions that observe
  14207. the C calling convention use the stack frame.  %@NL@%
  14208. %@NL@%
  14209. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  14210. %@NL@%
  14211. The stack frame for the assembly-language procedure shown in Figure 12.4 is
  14212. established by the following:  %@NL@%
  14213. %@NL@%
  14214. %@NL@%
  14215.   1.  The calling program pushes each of the parameters onto the stack,
  14216.       after which SP points to the last parameter pushed.%@NL@%
  14217. %@NL@%
  14218.   2.  The calling program issues a %@AB@%CALL%@AE@% instruction, which causes the return
  14219.       address (the place in the calling program to which control will
  14220.       ultimately return) to be placed on the stack. This address can be
  14221.       either two bytes long (for near calls) or four bytes long (for far
  14222.       calls). SP now points to this address.%@NL@%
  14223. %@NL@%
  14224.   3.  The first instruction of the called procedure saves the old value of
  14225.       BP, with the instruction %@AS@% push bp%@AE@%. SP now points to the saved copy of
  14226.       BP.%@NL@%
  14227. %@NL@%
  14228.   4.  BP is used to hold the current value of SP, with the instruction %@AS@% mov
  14229. %@AS@%      bp%@AE@%,%@AS@%sp%@AE@%. BP therefore now points to the old value of BP (saved on the
  14230.       stack).%@NL@%
  14231. %@NL@%
  14232.   5.  While BP remains constant throughout the procedure, SP is often
  14233.       decreased to provide room on the stack for local data or saved
  14234.       registers.%@NL@%
  14235. %@NL@%
  14236. %@NL@%
  14237. In general, the displacement (from BP) for a parameter %@AI@%x%@AE@% is equal to the
  14238. size of return address plus 2 plus the total size of parameters between %@AI@%x%@AE@%
  14239. and BP.  %@NL@%
  14240. %@NL@%
  14241. To calculate the size of parameters between %@AI@%x%@AE@% and BP, you must start with
  14242. the rightmost parameter because C pushes parameters from right to left. For
  14243. example, consider a %@AB@%FAR%@AE@% procedure that has one argument of type %@AB@%int%@AE@% (two
  14244. bytes). The displacement of the parameter is  %@NL@%
  14245. %@NL@%
  14246. %@AS@%  Argument's displacement = size of far return address + 2
  14247. %@AS@%                          = 4 + 2
  14248. %@AS@%                          = 6%@AE@%%@NL@%
  14249. %@NL@%
  14250. The argument can thus be loaded into BP with the following instruction:  %@NL@%
  14251. %@NL@%
  14252. %@AS@%  mov    bx,[bp+6]%@AE@%%@NL@%
  14253. %@NL@%
  14254. Once you determine the displacement of each parameter, you can use %@AB@%EQU
  14255. %@AB@%%@AE@%directives or structures to refer to the parameter with a single identifier
  14256. name in your assembly source code. For example, you can use a more readable
  14257. name to reference the parameter at %@AS@% BP+6 %@AE@% if you put the following statement
  14258. at the beginning of the assembly source file:  %@NL@%
  14259. %@NL@%
  14260. %@AS@%  Arg1    EQU    [bp+6]%@AE@%%@NL@%
  14261. %@NL@%
  14262. You can then refer to the first parameter in your source as %@AS@% Arg1 %@AE@% in any
  14263. instruction. Use of this feature is optional.  %@NL@%
  14264. %@NL@%
  14265. For far (segmented) addresses, Microsoft C pushes the segment address before
  14266. pushing the offset address. When pushing arguments larger than two bytes,
  14267. high-order words are always pushed before low-order words, and parameters
  14268. larger than two bytes are stored on the stack in most-significant,
  14269. least-significant order.  %@NL@%
  14270. %@NL@%
  14271. This standard for pushing segment addresses before pushing offset addresses
  14272. facilitates the use of the assembly-language instructions %@AB@%LDS%@AE@% (load data
  14273. segment) and %@AB@%LES%@AE@% (load extra segment).  %@NL@%
  14274. %@NL@%
  14275. %@NL@%
  14276. %@3@%%@CR:C6A00120037 @%%@AB@%12.8.7  Returning a Value%@AE@%%@EH@%%@NL@%
  14277. %@NL@%
  14278. Your assembly-language procedure can return a value to a C calling program.
  14279. All return values of four bytes or less are passed in registers. Far
  14280. pointers to return values larger than four bytes are returned in the DX and
  14281. AX registers. The DX register contains the segment address; the AX register
  14282. contains the offset relative to the segment contained in DX.  %@NL@%
  14283. %@NL@%
  14284. Table 12.3 shows the register conventions for returning simple data types to
  14285. a C program.  %@NL@%
  14286. %@NL@%
  14287. %@AB@%Table   %@AB@%12.3 Register Conventions for Simple Return Values%@AE@%%@AE@%
  14288.  
  14289. %@TH:  13   641 02 34 42 @%
  14290. Data Type                         Registers
  14291. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14292. %@AB@%char%@AE@%                              AL
  14293.  
  14294. %@AB@%int%@AE@%, %@AB@%short%@AE@%, %@AB@%_near *%@AE@%               AX
  14295.  
  14296. %@AB@%long%@AE@%, %@AB@%_far *%@AE@%                      High-order portion (or segment address) 
  14297.                                   in DX; 
  14298.                                   low-order portion (or offset address) in
  14299.                                   AX
  14300.  
  14301. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14302.  
  14303. %@TE:  13   641 02 34 42 @%
  14304.  
  14305. %@AU@% Your procedures can return structures.%@AE@%  %@NL@%
  14306. %@NL@%
  14307. To return a structure from a procedure that uses the C calling convention,
  14308. you must copy the structure to a global variable, then return a pointer to
  14309. that variable in the AX register (DX:AX, if you compiled in compact, large,
  14310. or huge model).  %@NL@%
  14311. %@NL@%
  14312. Procedures that use the FORTRAN/Pascal calling convention return structures
  14313. similarly, with the following exceptions:  %@NL@%
  14314. %@NL@%
  14315. %@NL@%
  14316.   ■   The calling program allocates space for the return value on the stack.%@NL@%
  14317. %@NL@%
  14318.   ■   The calling program passes a pointer to the location where the return
  14319.       value is to be placed in a hidden parameter.%@NL@%
  14320. %@NL@%
  14321.   ■   Instead of copying your structure into a global data item, you copy it
  14322.       into the location pointed to by the hidden parameter.%@NL@%
  14323. %@NL@%
  14324.   ■   You must still return the pointer to that location in the AX register
  14325.       (or DX:AX for far data models).%@NL@%
  14326. %@NL@%
  14327. %@NL@%
  14328. %@AU@% You can return floating-point values from your procedures.%@AE@%  %@NL@%
  14329. %@NL@%
  14330. Procedures that use the C calling convention and return type %@AB@%float%@AE@% or type
  14331. %@AB@%double%@AE@% must always copy their return values into the global variable %@AB@%fac%@AE@%. To
  14332. return floating-point values from procedures declared with the
  14333. FORTRAN/Pascal calling convention, you must return the result on the stack,
  14334. just as you would a structure.  %@NL@%
  14335. %@NL@%
  14336. To return a value of type %@AB@%long double%@AE@%, you must place the value on the
  14337. %@AB@%NDP%@AE@%(80%@AI@%x%@AE@%87) stack using the %@AB@%FLD %@AE@%instruction. The C run-time math routines
  14338. guarantee that the only value on the %@AB@%NDP %@AE@%stack is a return value; your
  14339. routines must observe the same rule.  %@NL@%
  14340. %@NL@%
  14341. %@NL@%
  14342. %@3@%%@CR:C6A00120038 @%%@AB@%12.8.8  Exiting the Procedure%@AE@%%@EH@%%@NL@%
  14343. %@NL@%
  14344. Before you exit your assembly-language procedure, you must perform several
  14345. steps to restore the calling program's environment. Some of these steps are
  14346. dependent on actions you took in allocating space for local variables and
  14347. preserving registers.  %@NL@%
  14348. %@NL@%
  14349. You must follow these steps (if appropriate to your procedure) in the order
  14350. shown:  %@NL@%
  14351. %@NL@%
  14352. %@NL@%
  14353.   1.  If you saved any of the registers SS, DS, SI, or DI, they must be
  14354.       popped off the stack in the reverse order from which they were saved.
  14355.       If you pop these registers in any other order, your program will
  14356.       behave incorrectly.%@NL@%
  14357. %@NL@%
  14358.   2.  If you allocated local data space at the beginning of the procedure,
  14359.       you must restore SP with the instruction %@AS@% mov s %@AE@% p %@AS@% ,bp%@AE@%.%@NL@%
  14360. %@NL@%
  14361.   3.  Restore BP with the instruction %@AS@% pop bp%@AE@%. This step is always
  14362.       necessary.%@NL@%
  14363. %@NL@%
  14364.   4.  Return to the calling program by issuing the %@AB@%ret%@AE@% instruction.%@NL@%
  14365. %@NL@%
  14366. %@NL@%
  14367. The following example shows the simplest possible entry and exit sequence.
  14368. In the entry sequence, no registers are saved and no local data space is
  14369. allocated.  %@NL@%
  14370. %@NL@%
  14371. %@AS@%  push   bp
  14372. %@AS@%  mov    bp,sp   ; Set up the new stack frame.
  14373. %@AS@%  .
  14374. %@AS@%  .
  14375. %@AS@%  .
  14376. %@AS@%  pop    bp      ; Restore the caller's stack frame.
  14377. %@AS@%  ret%@AE@%%@NL@%
  14378. %@NL@%
  14379. The following example shows an entry and exit sequence for a procedure that
  14380. saves SI and DI and allocates local data space on the stack.  %@NL@%
  14381. %@NL@%
  14382. %@AS@%  push   bp
  14383. %@AS@%  mov    bp,sp   ; Establish local stack frame.
  14384. %@AS@%  sub    sp,4    ; Allocate space for local data.
  14385. %@AS@%  push   si      ; Preserve the SI and DI registers.
  14386. %@AS@%  push   di
  14387. %@AS@%  .
  14388. %@AS@%  .
  14389. %@AS@%  .
  14390. %@AS@%  pop    di      ; Pop saved registers.
  14391. %@AS@%  pop    si
  14392. %@AS@%  mov    sp,bp   ; Free local data space.
  14393. %@AS@%  pop    bp      ; Restore old stack frame.
  14394. %@AS@%  ret%@AE@%%@NL@%
  14395. %@NL@%
  14396. %@NL@%
  14397. %@2@%%@CR:C6A00120039 @%%@AB@%12.9  Handling Data in Mixed-Language Programming%@AE@%%@EH@%%@NL@%
  14398. %@NL@%
  14399. This section contains detailed information about naming and calling
  14400. conventions in a mixed-language program. It also describes how various
  14401. languages represent strings, numerical data, arrays, and logical data.  %@NL@%
  14402. %@NL@%
  14403. %@NL@%
  14404. %@3@%%@CR:C6A00120040 @%%@AB@%12.9.1  Default Naming and Calling Conventions%@AE@%%@EH@%%@NL@%
  14405. %@NL@%
  14406. Each language has its own default naming and calling conventions (Table
  14407. 12.4).  %@NL@%
  14408. %@NL@%
  14409. %@AB@%Table 12.4  %@AB@%Default Naming and Calling Conventions%@AE@%%@AE@%
  14410.  
  14411. %@TH:  15   723 03 10 19 19 28 @%
  14412.           Calling            Naming             Parameter 
  14413. Language  Convention         Convention         Passing
  14414. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14415. BASIC     FORTRAN/Pascal     Case insensitive   Near reference
  14416.  
  14417. C         C                  Case sensitive     Value (scalar variables), 
  14418.                                                 reference (arrays and 
  14419.                                                 pointers)
  14420.  
  14421. FORTRAN   FORTRAN/Pascal     Case insensitive   Reference
  14422.  
  14423. Pascal    FORTRAN/Pascal     Case insensitive   Value
  14424.  
  14425. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14426.  
  14427. %@TE:  15   723 03 10 19 19 28 @%
  14428.  
  14429. %@NL@%
  14430. %@4@%%@AB@%BASIC Conventions%@AE@%%@EH@%%@NL@%
  14431. %@NL@%
  14432. When you call BASIC routines from C, you must pass all arguments by near
  14433. reference (near pointer). You can modify the conventions observed by BASIC
  14434. routines that interface with C functions by using the %@AB@%DECLARE%@AE@%, %@AB@%BYVAL%@AE@%, %@AB@%SEG%@AE@%,
  14435. and %@AB@%CALLS%@AE@% keywords. For more information on these keywords, see the
  14436. %@AI@%Microsoft BASIC Language Reference%@AE@% or the %@AI@%Microsoft BASIC Programmer's
  14437. %@AI@%Guide%@AE@%.  %@NL@%
  14438. %@NL@%
  14439. %@NL@%
  14440. %@4@%%@AB@%FORTRAN Conventions%@AE@%%@EH@%%@NL@%
  14441. %@NL@%
  14442. You can modify the conventions observed by FORTRAN routines that call C
  14443. functions by using the %@AB@%INTERFACE%@AE@%, %@AB@%VALUE%@AE@%, %@AB@%PASCAL%@AE@%, and %@AB@%C%@AE@% keywords. For more
  14444. information about the use of these keywords, see the%@AI@% Microsoft FORTRAN%@AE@%
  14445. %@AI@%Reference.%@AE@%  %@NL@%
  14446. %@NL@%
  14447. %@NL@%
  14448. %@4@%%@AB@%Pascal Conventions%@AE@%%@EH@%%@NL@%
  14449. %@NL@%
  14450. You can modify the conventions observed by Pascal routines that interface
  14451. with C functions by using the %@AB@%VAR%@AE@%, %@AB@%CONST%@AE@%, %@AB@%ADR%@AE@%, %@AB@%VARS%@AE@%, %@AB@%CONSTS%@AE@%, %@AB@%ADRS%@AE@%, and %@AB@%C%@AE@%
  14452. keywords. For more information about the use of these keywords, see the
  14453. %@AI@%Microsoft Pascal Compiler User's Guide.%@AE@%  %@NL@%
  14454. %@NL@%
  14455. %@NL@%
  14456. %@3@%%@CR:C6A00120041 @%%@AB@%12.9.2  Numeric Data Representation%@AE@%%@EH@%%@NL@%
  14457. %@NL@%
  14458. Table 12.5 shows how to declare numeric variables of similar type in
  14459. different languages.  %@NL@%
  14460. %@NL@%
  14461. %@AB@%Table 12.5  %@AB@%Equivalent Numeric Data Types%@AE@%%@AE@%
  14462.  
  14463. %@TH:  34  1857 02 14 20 23 19 @%
  14464. BASIC         C                   FORTRAN                Pascal
  14465. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14466. %@AI@%x%@AE@%%@AB@%%%@AE@%            %@AB@%short%@AE@%               %@AB@%INTEGER*2 %@AE@%             %@AB@%INTEGER2%@AE@%
  14467.  
  14468. %@AB@%INTEGER%@AE@%       %@AB@%int%@AE@%                 ---                    %@AB@%INTEGER %@AE@%
  14469.                                                          (default)
  14470.  
  14471. ---           %@AB@%unsigned short%@AE@%%@AU@%(1)%@AE@%   ---                    %@AB@%WORD%@AE@%
  14472.  
  14473. ---           %@AB@%unsigned%@AE@%            ---                    ---
  14474.  
  14475. %@AI@%x%@AE@%%@AB@%&%@AE@%            %@AB@%long%@AE@%                %@AB@%INTEGER*4%@AE@%              %@AB@%INTEGER4%@AE@%
  14476.  
  14477. %@AB@%LONG%@AE@%          ---                 %@AB@%INTEGER%@AE@% (default)      ---
  14478.  
  14479. ---           %@AB@%unsigned long%@AE@%%@AU@%(1)%@AE@%    ---                    ---
  14480.  
  14481. %@AI@%x%@AE@%%@AB@%!%@AE@%            %@AB@%float%@AE@%               %@AB@%REAL*4%@AE@%                 %@AB@%REAL4%@AE@%
  14482.  
  14483. %@AI@%x%@AE@% (default)   ---                 %@AB@%REAL%@AE@%                   %@AB@%REAL%@AE@% (default)
  14484.  
  14485. %@AB@%SINGLE%@AE@%        ---                 ---                    ---
  14486.  
  14487. %@AI@%x%@AE@%%@AB@%#%@AE@%            %@AB@%double%@AE@%              %@AB@%REAL*8%@AE@%                 %@AB@%REAL8%@AE@%
  14488.  
  14489. %@AB@%DOUBLE%@AE@%        ---                 %@AB@%DOUBLE %@AE@%                ---
  14490.                                   %@AB@%PRECISION%@AE@%              
  14491.  
  14492. ---           %@AB@%long double%@AE@%         %@AB@%REAL*16%@AE@%                %@AB@%REAL16%@AE@%
  14493.  
  14494. ---           %@AB@%unsigned char%@AE@%       %@AB@%CHARACTER*1%@AE@%%@AU@%(2)%@AE@%         %@AB@%CHAR%@AE@%
  14495.  
  14496. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14497.  
  14498. %@TE:  34  1857 02 14 20 23 19 @%
  14499.  
  14500. %@AU@%(1) %@AE@% Types %@AB@%unsigned short%@AE@% and %@AB@%unsigned long%@AE@% are not supported by BASIC or
  14501. FORTRAN. Type  %@AB@%unsigned long %@AE@%is not supported by Pascal. A signed integral
  14502. type can be substituted, but the maximum range will be less.  
  14503. %@AU@%(2) %@AE@% The FORTRAN type %@AB@%CHARACTER*1 %@AE@%is not the same as %@AB@%LOGICAL%@AE@%. %@NL@%
  14504. %@NL@%
  14505. %@NL@%
  14506. The FORTRAN types %@AB@%COMPLEX*8%@AE@% and %@AB@%COMPLEX*16%@AE@% are not implemented in C but can
  14507. be represented with structures.  %@NL@%
  14508. %@NL@%
  14509. The FORTRAN types %@AB@%LOGICAL*2%@AE@% and %@AB@%LOGICAL*4%@AE@% are not implemented in C.
  14510. %@AB@%LOGICAL*2%@AE@% is stored as a one-byte Boolean indicator followed by an unused
  14511. byte; %@AB@%LOGICAL*4%@AE@% is stored as a one-byte Boolean indicator followed by three
  14512. unused bytes.  %@NL@%
  14513. %@NL@%
  14514. %@NL@%
  14515. %@3@%%@CR:C6A00120042 @%%@AB@%12.9.3  Strings%@AE@%%@EH@%%@NL@%
  14516. %@NL@%
  14517. Each language implements strings differently. This section describes the
  14518. ways that strings are implemented in Microsoft languages.  %@NL@%
  14519. %@NL@%
  14520. %@NL@%
  14521. %@4@%%@AB@%C String Format%@AE@%%@EH@%%@NL@%
  14522. %@NL@%
  14523. C stores strings as arrays of bytes and uses a null character ( %@AS@% '\0' %@AE@% ) as
  14524. an end-of-string delimiter. For example, consider the following string:  %@NL@%
  14525. %@NL@%
  14526. %@AS@%  char c_string[] = "C text string";%@AE@%%@NL@%
  14527. %@NL@%
  14528. This string is represented in memory as follows:  %@NL@%
  14529. %@NL@%
  14530. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  14531. %@NL@%
  14532. Because %@AS@% c_string %@AE@% is an array like any other, C passes it by reference in
  14533. function calls.  %@NL@%
  14534. %@NL@%
  14535. %@NL@%
  14536. %@4@%%@AB@%BASIC String Format%@AE@%%@EH@%%@NL@%
  14537. %@NL@%
  14538. BASIC stores strings as four-byte descriptors pointing to the actual string
  14539. data. The format of the descriptor is as follows:  %@NL@%
  14540. %@NL@%
  14541. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  14542. %@NL@%
  14543. The first field of the string descriptor contains an integer indicating the
  14544. length (in bytes) of the string. The second field contains the address of
  14545. the string in the default data segment.  %@NL@%
  14546. %@NL@%
  14547. Do not attempt to alter the length of BASIC strings, because they are
  14548. managed by BASIC string-space management routines. You cannot count on a
  14549. particular string remaining at a given offset during the execution of a
  14550. BASIC program because the BASIC string-space management routines allocate
  14551. strings to different areas of memory depending on program requirements.  %@NL@%
  14552. %@NL@%
  14553. The format of the string at DS:%@AI@%Address%@AE@% is a simple array of characters. The
  14554. string is exactly the length indicated in the descriptor.  %@NL@%
  14555. %@NL@%
  14556. %@AU@% To pass a BASIC string to C, append a null character.%@AE@%  %@NL@%
  14557. %@NL@%
  14558. Because C needs the null character to delimit the end of the string, you
  14559. should append %@AS@% chr$( 0 ) %@AE@% to your BASIC string before passing it to your C
  14560. function. For example,  %@NL@%
  14561. %@NL@%
  14562. %@AS@%  A$ = "I am a BASIC string"
  14563. %@AS@%  A$ = A$ + chr$( 0 )
  14564. %@AS@%  
  14565. %@AS@%  CALL CFunc( SADD(A$) )%@AE@%%@NL@%
  14566. %@NL@%
  14567. Note that the BASIC call is made by near reference using the %@AB@%SADD %@AE@%keyword.  %@NL@%
  14568. %@NL@%
  14569. %@AU@% Use a string descriptor to pass a C string to BASIC.%@AE@%  %@NL@%
  14570. %@NL@%
  14571. To pass a C string to BASIC, create a structure for the string descriptor.
  14572. For example,  %@NL@%
  14573. %@NL@%
  14574. %@AS@%  char c_string[] = "C String Data";
  14575. %@AS@%  
  14576. %@AS@%  struct tagBASICStringDes
  14577. %@AS@%  {
  14578. %@AS@%      char *   sd_addr;
  14579. %@AS@%      int      sd_len;
  14580. %@AS@%  } str_des;
  14581. %@AS@%  
  14582. %@AS@%  str_des.sd_addr = c_string;
  14583. %@AS@%  str_des.sd_len = strlen( c_string );
  14584. %@AS@%  
  14585. %@AS@%  BASICFunction( &str_des );%@AE@%%@NL@%
  14586. %@NL@%
  14587. %@NL@%
  14588. %@4@%%@AB@%FORTRAN String Format%@AE@%%@EH@%%@NL@%
  14589. %@NL@%
  14590. FORTRAN stores strings as a series of bytes at a fixed location in memory.
  14591. There is no delimiter at the end of the string. Consider the string declared
  14592. as follows:  %@NL@%
  14593. %@NL@%
  14594. %@AS@%  STR = 'FORTRAN STRING'%@AE@%%@NL@%
  14595. %@NL@%
  14596. The string is stored in memory as follows:  %@NL@%
  14597. %@NL@%
  14598. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  14599. %@NL@%
  14600. FORTRAN passes strings by reference, as it does all other data.  %@NL@%
  14601. %@NL@%
  14602. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14603. NOTE
  14604.  
  14605. %@AI@%FORTRAN's variable length strings cannot be used in mixed-language
  14606. %@AI@%programming because the temporary variable used to communicate string length
  14607. %@AI@%is not accessible to other languages.%@AE@%%@NL@%
  14608. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  14609. %@NL@%
  14610. To pass a C string to FORTRAN (or Pascal), pass the variable by reference as
  14611. you normally would. In your FORTRAN or Pascal routine, you must specify the
  14612. length of the string; strings that are passed as arguments from one language
  14613. to another must be of fixed length.  %@NL@%
  14614. %@NL@%
  14615. %@NL@%
  14616. %@4@%%@AB@%Pascal String Format%@AE@%%@EH@%%@NL@%
  14617. %@NL@%
  14618. Pascal represents strings as fixed-length arrays of %@AB@%CHAR%@AE@% or as strings with
  14619. a length byte followed by the string data.  %@NL@%
  14620. %@NL@%
  14621. %@AU@% To pass a fixed-length string to C, append a null character.%@AE@%  %@NL@%
  14622. %@NL@%
  14623. To pass a fixed-length string to a C function, use the concatenation
  14624. operator (%@AB@%*%@AE@%) to append a null character. Then pass the string to the C
  14625. function by reference (by declaring the string as %@AB@%CONST%@AE@%, %@AB@%CONSTS%@AE@%, %@AB@%VAR%@AE@%, or
  14626. %@AB@%VARS%@AE@%). For example,  %@NL@%
  14627. %@NL@%
  14628. %@AS@%  PROGRAM PasStr( input, output );
  14629. %@AS@%  type
  14630. %@AS@%      stype15 = string(15);  { fixed-length }
  14631. %@AS@%  var
  14632. %@AS@%      str : stype15;
  14633. %@AS@%  
  14634. %@AS@%  PROCEDURE PasStrToC( VAR s1 : stype15 ) [C]; EXTERN;
  14635. %@AS@%  
  14636. %@AS@%  BEGIN
  14637. %@AS@%      str := 'Pass this to C' * chr( 0 );
  14638. %@AS@%      PasStrToC( str );
  14639. %@AS@%  END.%@AE@%%@NL@%
  14640. %@NL@%
  14641. A more flexible way to pass Pascal strings to C functions is to declare them
  14642. as type %@AB@%ADRMEM%@AE@% or %@AB@%ADSMEM%@AE@%, then pass the address of the string. For example,
  14643. %@NL@%
  14644. %@NL@%
  14645. %@AS@%  PROCEDURE PasStrToC( s1adr : ADRMEM ) [C]; EXTERN;%@AE@%%@NL@%
  14646. %@NL@%
  14647. Then you can call the C function with this code:  %@NL@%
  14648. %@NL@%
  14649. %@AS@%  PasStrToC( ADR str );%@AE@%%@NL@%
  14650. %@NL@%
  14651. Using this method, you can pass strings of different lengths to C functions.
  14652. %@NL@%
  14653. %@NL@%
  14654. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14655. NOTE
  14656.  
  14657. %@AI@%The Pascal type %@AI@%LSTRING %@AE@%%@AI@%is not compatible with C; you can pass a string
  14658. %@AI@%declared as LSTRING %@AE@%%@AI@%by first assigning it to another variable of type
  14659. %@AI@%STRING%@AE@%%@AI@%, then passing that variable.%@AE@%%@AE@%%@NL@%
  14660. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  14661. %@NL@%
  14662. Whenever you pass a variable of type %@AB@%STRING%@AE@% or type %@AB@%LSTRING%@AE@% by value, Pascal
  14663. pushes the whole string onto the stack and passes the length of the string
  14664. as another parameter. C cannot access strings passed in this manner.  %@NL@%
  14665. %@NL@%
  14666. %@AU@% Before passing a string from C to Pascal, make sure enough space is
  14667. %@AU@%allocated.%@AE@%  %@NL@%
  14668. %@NL@%
  14669. Passing a string from a C function to a Pascal function or procedure is
  14670. identical to passing a string from a C function to a FORTRAN routine. The
  14671. only provision you must make is to specify the length of the string to your
  14672. Pascal function.  %@NL@%
  14673. %@NL@%
  14674. %@NL@%
  14675. %@3@%%@CR:C6A00120043 @%%@AB@%12.9.4  Arrays%@AE@%%@EH@%%@NL@%
  14676. %@NL@%
  14677. When you use an array in a program written in a single language, the method
  14678. for array handling is consistent. When you mix languages, you need to be
  14679. aware of the differences between array-handling techniques in various
  14680. languages.  %@NL@%
  14681. %@NL@%
  14682. Unlike most Microsoft languages, BASIC keeps an array descriptor, which is
  14683. similar to the BASIC string descriptor discussed in Section 12.9.3,
  14684. "Strings." This array descriptor is necessary because BASIC handles memory
  14685. allocation for arrays dynamically (at run time). Dynamic allocation requires
  14686. BASIC to shift arrays in memory.  %@NL@%
  14687. %@NL@%
  14688. %@AU@% To pass a BASIC array to a  C function, use the %@AE@%%@AB@%VARPTR%@AE@% and %@AB@%VARSEG %@AE@%keywords.
  14689. %@NL@%
  14690. %@NL@%
  14691. The %@AB@%VARPTR %@AE@%and %@AB@%VARSEG %@AE@%keywords obtain the address of the first element of
  14692. the array and its segment, respectively. The example below shows how to call
  14693. a C function with a near reference and a far reference to an array:  %@NL@%
  14694. %@NL@%
  14695. %@AS@%  DIM ARRAY%( 20 )
  14696. %@AS@%  DECLARE CNearArray CDECL( BYVAL Addr AS INTEGER )
  14697. %@AS@%  DECLARE CFarArray CDECL( BYVAL Addr AS INTEGER, BYVAL Seg AS INTEGER )
  14698. %@AS@%  .
  14699. %@AS@%  .
  14700. %@AS@%  .
  14701. %@AS@%  CALL CNearArray( VARPTR( ARRAY%(0) ) )
  14702. %@AS@%  CALL CFarArray( VARPTR( ARRAY%(0) ), VARSEG( ARRAY%(0) ) )%@AE@%%@NL@%
  14703. %@NL@%
  14704. The C functions receiving %@AS@% ARRAY %@AE@% can be declared as follows:  %@NL@%
  14705. %@NL@%
  14706. %@AS@%  _cdecl CNearArray( int * array );
  14707. %@AS@%  _cdecl CFarArray( int far * array );%@AE@%%@NL@%
  14708. %@NL@%
  14709. The routine that receives the array must not make a call back to BASIC. If
  14710. it does, the location of the array data could change, and the address that
  14711. was passed to the routine would become meaningless.  %@NL@%
  14712. %@NL@%
  14713. If you only need to pass one member of the array from BASIC to your C
  14714. function, you can pass it by value as follows:  %@NL@%
  14715. %@NL@%
  14716. %@AS@%  CALL CFunc( ARRAY%(8) )%@AE@%%@NL@%
  14717. %@NL@%
  14718. %@NL@%
  14719. %@3@%%@CR:C6A00120044 @%%@AB@%12.9.5  Array Declaration and Indexing%@AE@%%@EH@%%@NL@%
  14720. %@NL@%
  14721. Each language varies in the way that arrays are declared and indexed. Array
  14722. indexing is a source-level consideration and involves no transformation of
  14723. data. There are two differences in the way elements are indexed by each
  14724. language:  %@NL@%
  14725. %@NL@%
  14726. %@NL@%
  14727.   1.  The value of the lower array bound is different among Microsoft
  14728.       languages.%@NL@%
  14729. %@NL@%
  14730. %@STUB@%      By default, FORTRAN indexes the first element of an array as 1. BASIC
  14731.       and C index it as 0. Pascal lets you begin indexing at any integer
  14732.       value. Recent versions of BASIC and FORTRAN also give you the option
  14733.       of specifying lower bounds at any integer value.%@NL@%
  14734. %@NL@%
  14735.   2.  Some languages vary subscripts in row-major order; others vary
  14736.       subscripts in column-major order.%@NL@%
  14737. %@NL@%
  14738. %@STUB@%      This issue only affects arrays with more than one dimension. With
  14739.       row-major order (used by C and Pascal), the rightmost dimension
  14740.       changes first. With column-major order (used by FORTRAN, and BASIC by
  14741.       default), the leftmost dimension changes first. Thus, in C, the first
  14742.       four elements of an array declared as %@AS@% X[3][3] %@AE@% are%@NL@%
  14743. %@NL@%
  14744. %@AS@%      X[0][0]    X[0][1]    X[0][2]    X[1][0]%@AE@%%@NL@%
  14745. %@NL@%
  14746. %@STUB@%      In FORTRAN, the four elements are%@NL@%
  14747. %@NL@%
  14748. %@AS@%      X(1,1)     X(2,1)     X(3,1)     X(1,2)%@AE@%%@NL@%
  14749. %@NL@%
  14750. %@STUB@%      The C and FORTRAN arrays shown above illustrate the difference between
  14751.       row-major and column-major order as well as the difference in the
  14752.       assumed lower bound between C and FORTRAN. Table 12.6 shows
  14753.       equivalences for array declarations in each language. In this table, %@AI@%r%@AE@%
  14754.       is the number of elements of the row dimension (which changes most
  14755.       slowly), and %@AI@%c%@AE@% is the number of elements of the column dimension
  14756.       (which changes most quickly).%@NL@%
  14757. %@AB@%Table 12.6  %@AB@%Equivalent Array Declarations%@AE@%%@AE@%
  14758.  
  14759. %@TH:  14   951 02 10 33 33 @%
  14760. Language  Array Declaration                Notes
  14761. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14762. BASIC     %@AB@%DIM%@AE@% %@AI@%x%@AE@%(%@AI@%r%@AE@%-1, %@AI@%c%@AE@%-1)                  With default lower bounds of 0
  14763.  
  14764. C         type %@AI@%x%@AE@%[%@AI@%r%@AE@%][%@AI@%c%@AE@%]%@AB@%%@AE@%                     When passed by reference
  14765.           %@AB@%struct %@AE@%{ %@AI@%type%@AE@% %@AI@%x%@AE@%[%@AI@%r%@AE@%][%@AI@%c%@AE@%]; } %@AI@%x%@AE@%       When passed by value
  14766.  
  14767. FORTRAN   %@AI@%type x%@AE@%(%@AI@%c%@AE@%, %@AI@%r%@AE@%)                     With default lower bounds of 1
  14768.  
  14769. Pascal    %@AI@%x%@AE@% : %@AB@%ARRAY%@AE@% [%@AI@%a%@AE@%..%@AI@%a%@AE@%+%@AI@%r%@AE@%-1, %@AI@%b%@AE@%..%@AI@%b%@AE@%+%@AI@%c%@AE@%-1]%@AB@% %@AE@%
  14770.           %@AB@%OF%@AE@% %@AI@%type%@AE@%
  14771.  
  14772. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14773.  
  14774. %@TE:  14   951 02 10 33 33 @%
  14775.  
  14776. %@NL@%
  14777. %@NL@%
  14778. The order of indexing extends to any number of dimensions you declare. For
  14779. example, the C declaration  %@NL@%
  14780. %@NL@%
  14781. %@AS@%  int arr1[2][10][15][20];%@AE@%%@NL@%
  14782. %@NL@%
  14783. is equivalent to the FORTRAN declaration  %@NL@%
  14784. %@NL@%
  14785. %@AS@%  INTEGER*2 ARR1( 20, 15, 10, 2 )%@AE@%%@NL@%
  14786. %@NL@%
  14787. The constants used in a C array declaration represent dimensions, not upper
  14788. bounds as they do in other languages. Therefore, the last element in the C
  14789. array declared as %@AS@% int arr[5][5] %@AE@% is %@AS@% arr[4][4]%@AE@%, not %@AS@% arr[5][5]%@AE@%.  %@NL@%
  14790. %@NL@%
  14791. %@NL@%
  14792. %@3@%%@CR:C6A00120045 @%%@AB@%12.9.6  Structures, Records, and User-Defined Types%@AE@%%@EH@%%@NL@%
  14793. %@NL@%
  14794. The C %@AB@%struct %@AE@%type, the BASIC user-defined type, the FORTRAN record (defined
  14795. with the %@AB@%STRUCTURE %@AE@%keyword), and the Pascal %@AB@%record %@AE@%type are equivalent.
  14796. Therefore, these data types can be passed between C, FORTRAN, Pascal, and
  14797. BASIC.  %@NL@%
  14798. %@NL@%
  14799. These types can be affected by the storage method. By default, C, FORTRAN,
  14800. and Pascal use word alignment for types shorter than one word (type %@AB@%char %@AE@%and
  14801. %@AB@%unsigned char%@AE@%). This storage method specifies that occasional bytes can be
  14802. inserted as padding so that word and double-word objects start on an even
  14803. boundary. (In addition, all nested structures and records start on a word
  14804. boundary.)  %@NL@%
  14805. %@NL@%
  14806. If you are passing a structure or record across a mixed-language interface,
  14807. your calling routine and called routine must agree on the storage method and
  14808. parameter-passing convention. Otherwise, data will not be interpreted
  14809. correctly.  %@NL@%
  14810. %@NL@%
  14811. Because Pascal, FORTRAN, and C use the same storage method for structures
  14812. and records, you can interchange data between routines without taking any
  14813. special precautions unless you modify the storage method. Make sure the
  14814. storage methods agree before interchanging data between C, FORTRAN, and
  14815. Pascal.  %@NL@%
  14816. %@NL@%
  14817. BASIC packs user-defined types, so your C function must also pack structures
  14818. (using the /Zp command-line option or the %@AB@%pack%@AE@% pragma) to agree.  %@NL@%
  14819. %@NL@%
  14820. You can pass structures as parameters by value or by reference. Both the
  14821. calling program and the called program must agree on the parameter-passing
  14822. convention. See Section 12.2.3, "Parameter-Passing Requirement," for more
  14823. information about the language you are using.  %@NL@%
  14824. %@NL@%
  14825. %@NL@%
  14826. %@3@%%@CR:C6A00120046 @%%@AB@%12.9.7  External Data%@AE@%%@EH@%%@NL@%
  14827. %@NL@%
  14828. External data refers to data that is both static and public; that is, the
  14829. data is stored in a set place in memory as opposed to being allocated on the
  14830. stack, and the data is visible to other modules.  %@NL@%
  14831. %@NL@%
  14832. External data can be defined in C, Pascal, and assembly language. Note that
  14833. a data definition is distinct from an external declaration. A data
  14834. definition causes a compiler to create a data object; an external
  14835. declaration informs a compiler that the object is to be found in another
  14836. module. FORTRAN can only define external data in COMMON blocks. (See Section
  14837. 12.9.9, "Common Blocks," for more information about sharing external data
  14838. with FORTRAN programs.)  %@NL@%
  14839. %@NL@%
  14840. There are three requirements for programs that share external data between
  14841. languages:  %@NL@%
  14842. %@NL@%
  14843. %@NL@%
  14844.   1.  One of the modules must define the data.%@NL@%
  14845. %@NL@%
  14846. %@STUB@%      You can define a static data object in a C module by defining a data
  14847.       object outside all functions. (If you use the %@AB@%static%@AE@% keyword in C,
  14848.       however, the data object will not be made public.)%@NL@%
  14849. %@NL@%
  14850.   2.  The other modules that will access the data must declare the data as
  14851.       external.%@NL@%
  14852. %@NL@%
  14853. %@STUB@%      In C, you can declare data as external by using an %@AB@%extern%@AE@% declaration,
  14854.       similar to the %@AB@%extern%@AE@% declaration for functions. In FORTRAN and
  14855.       Pascal, you can declare data as external by adding the %@AB@%EXTERN
  14856. %@AB@%      %@AE@%attribute to the data declaration.%@NL@%
  14857. %@NL@%
  14858.   3.  Resolve naming-convention differences.%@NL@%
  14859. %@NL@%
  14860. %@STUB@%      In C, you can adopt the FORTRAN/Pascal naming convention by applying
  14861.       %@AB@%_fortran %@AE@%or %@AB@%_pascal %@AE@%to the data declaration. In FORTRAN and Pascal,
  14862.       you can adopt the C naming convention by applying the %@AB@%C %@AE@%attribute to
  14863.       the data declaration.%@NL@%
  14864. %@NL@%
  14865. %@NL@%
  14866. %@NL@%
  14867. %@3@%%@CR:C6A00120047 @%%@AB@%12.9.8  Pointers and Address Variables%@AE@%%@EH@%%@NL@%
  14868. %@NL@%
  14869. Rather than passing data directly, you may want to pass the address of a
  14870. piece of data. Passing the address amounts to passing the data by reference.
  14871. In some cases, such as in BASIC arrays, there is no other way to pass a data
  14872. item as a parameter.  %@NL@%
  14873. %@NL@%
  14874. C programs always pass array variables by address. All other types are
  14875. passed by value unless you use the address-of (%@AB@%&%@AE@%) operator to obtain the
  14876. address.  %@NL@%
  14877. %@NL@%
  14878. The Pascal %@AB@%ADR %@AE@%and %@AB@%ADS %@AE@%types are equivalent to near and far pointers,
  14879. respectively, in C. You can pass %@AB@%ADR %@AE@%and %@AB@%ADS %@AE@%variables as %@AB@%ADRMEM %@AE@%or %@AB@%ADSMEM%@AE@%.
  14880. BASIC and FORTRAN do not have formal address types. However, they do provide
  14881. ways for storing and passing addresses.  %@NL@%
  14882. %@NL@%
  14883. BASIC programs can access a variable's segment address with the %@AB@%VARSEG
  14884. %@AB@%%@AE@%function and its offset address with the %@AB@%VARPTR%@AE@% function. The values
  14885. returned by these intrinsic functions should then be passed or stored as
  14886. ordinary integer variables. If you pass them to another language, pass by
  14887. value. Otherwise you will be attempting to pass the address of the address,
  14888. rather than the address itself.  %@NL@%
  14889. %@NL@%
  14890. To pass a near address, pass only the offset; if you need to pass a far
  14891. address, you may have to pass the segment and the offset separately. Pass
  14892. the segment address first, unless %@AB@%CDECL %@AE@%is in effect.  %@NL@%
  14893. %@NL@%
  14894. FORTRAN programs can determine near and far addresses with the %@AB@%LOC %@AE@%and
  14895. %@AB@%LOCFAR %@AE@%functions. Store the result of the %@AB@%LOC %@AE@%function as %@AB@%INTEGER*2 %@AE@%and the
  14896. result of the %@AB@%LOCFAR %@AE@%function as %@AB@%INTEGER*4%@AE@%.  %@NL@%
  14897. %@NL@%
  14898. As with BASIC, if you pass the result of %@AB@%LOC %@AE@%or %@AB@%LOCFAR %@AE@%to another language,
  14899. be sure to pass by value.  %@NL@%
  14900. %@NL@%
  14901. %@NL@%
  14902. %@3@%%@CR:C6A00120048 @%%@AB@%12.9.9  Common Blocks%@AE@%%@EH@%%@NL@%
  14903. %@NL@%
  14904. You can pass individual members of a FORTRAN or BASIC common block in an
  14905. argument list, just as you can any data item. However, you can also give a
  14906. different language module access to the entire common block at once.  %@NL@%
  14907. %@NL@%
  14908. C modules can reference the items of a common block by first declaring a
  14909. structure with fields that correspond to the common-block variables. Having
  14910. defined a structure with the appropriate fields, the C module must then
  14911. connect with the common block itself. The next two sections present methods
  14912. for gaining access to common blocks.  %@NL@%
  14913. %@NL@%
  14914. %@NL@%
  14915. %@4@%%@AB@%Passing the Address of a Common Block%@AE@%%@EH@%%@NL@%
  14916. %@NL@%
  14917. To pass the address of a common block, simply pass the address of the first
  14918. variable in the block. (In other words, pass the first variable by
  14919. reference.) The receiving C module should expect to receive a structure by
  14920. reference.  %@NL@%
  14921. %@NL@%
  14922. In the example below, the C function %@AS@% initcb %@AE@% receives the address of the
  14923. variable %@AS@% N%@AE@%, which it considers to be a pointer to a structure with three
  14924. fields:  %@NL@%
  14925. %@NL@%
  14926. %@AS@%  C      FORTRAN SOURCE CODE
  14927. %@AS@%  C
  14928. %@AS@%         COMMON /CBLOCK/N, X, Y
  14929. %@AS@%         INTEGER*2 N
  14930. %@AS@%         REAL*8    X, Y
  14931. %@AS@%  .
  14932. %@AS@%  .
  14933. %@AS@%  .
  14934. %@AS@%         CALL INITCB( N )
  14935. %@AS@%  
  14936. %@AS@%  
  14937. %@AS@%  /* C source code */
  14938. %@AS@%  
  14939. %@AS@%  
  14940. %@AS@%  /* Explicitly set structure packing to word-alignment */
  14941. %@AS@%  #pragma pack( 2 );
  14942. %@AS@%  
  14943. %@AS@%  struct block_type
  14944. %@AS@%  {
  14945. %@AS@%      int     n;
  14946. %@AS@%      double  x;
  14947. %@AS@%      double  y;
  14948. %@AS@%  };
  14949. %@AS@%  
  14950. %@AS@%  initcb( struct block_type * block_hed )
  14951. %@AS@%  {
  14952. %@AS@%      block_hed-n = 1;
  14953. %@AS@%      block_hed-x = 10.0;
  14954. %@AS@%      block_hed-y = 20.0;
  14955. %@AS@%  }%@AE@%%@NL@%
  14956. %@NL@%
  14957. %@NL@%
  14958. %@4@%%@AB@%Accessing Common Blocks Directly%@AE@%%@EH@%%@NL@%
  14959. %@NL@%
  14960. You can access FORTRAN common blocks directly by defining a structure with
  14961. the appropriate fields and then using the methods described in Section
  14962. 12.9.7, "External Data." Here is an example of accessing common blocks
  14963. directly:  %@NL@%
  14964. %@NL@%
  14965. %@AS@%  struct block_type
  14966. %@AS@%  {
  14967. %@AS@%      int    n;
  14968. %@AS@%      double x;
  14969. %@AS@%      double y;
  14970. %@AS@%  };
  14971. %@AS@%  
  14972. %@AS@%  extern struct block_type fortran cblock;%@AE@%%@NL@%
  14973. %@NL@%
  14974. %@AU@% You cannot access common blocks directly using BASIC common blocks.%@AE@%  %@NL@%
  14975. %@NL@%
  14976. Note that the technique of accessing common blocks directly works with
  14977. FORTRAN common blocks, but not with BASIC common blocks. If your C module
  14978. must work with both FORTRAN and BASIC common blocks, pass the address of the
  14979. common block as a parameter to the function.  %@NL@%
  14980. %@NL@%
  14981. %@NL@%
  14982. %@3@%%@CR:C6A00120049 @%%@AB@%12.9.10  Using a Varying Number of Parameters%@AE@%%@EH@%%@NL@%
  14983. %@NL@%
  14984. Some C functions (for example %@AB@%printf%@AE@%) accept a variable number of
  14985. parameters. To call such a function from another language, you need to
  14986. suppress the type-checking that normally forces a call to be made with a
  14987. fixed number of parameters. In BASIC, you can remove this type-checking by
  14988. omitting a parameter list from the %@AB@%DECLARE %@AE@%statement. In FORTRAN or Pascal,
  14989. you can call routines with a variable number of parameters by including the
  14990. %@AB@%VARYING %@AE@%attribute in your interface to the routine, along with the %@AB@%C
  14991. %@AB@%%@AE@%attribute. You must use the %@AB@%C%@AE@% attribute because a variable number of
  14992. parameters is feasible only with the C calling convention.  %@NL@%
  14993. %@NL@%
  14994. %@NL@%
  14995. %@NL@%
  14996. %@NL@%
  14997. %@NL@%
  14998. %@NL@%
  14999. %@CR:C6A00130001 @%%@1@%%@AB@%Chapter 13  Writing Portable Programs%@AE@%%@EH@%%@NL@%
  15000. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15001. %@NL@%
  15002. Because C compilers exist on a variety of computers, some C applications
  15003. developed for one computer system can be ported to other systems. However,
  15004. some aspects of language behavior depend on how a particular C compiler is
  15005. implemented and how a specific computer operates. Therefore, when designing
  15006. a program to be ported to another system, it is important that you examine
  15007. programming assumptions.  %@NL@%
  15008. %@NL@%
  15009. This chapter describes programming assumptions that can affect writing
  15010. portable programs.  %@NL@%
  15011. %@NL@%
  15012. The American National Standards Institute Standard for the C Language (the
  15013. ANSI Standard) details every instance where language behavior is defined by
  15014. the implementation. Appendix C summarizes implementation-defined behavior
  15015. for Microsoft C.  %@NL@%
  15016. %@NL@%
  15017. %@NL@%
  15018. %@2@%%@CR:C6A00130002 @%%@AB@%13.1  Assumptions about Hardware%@AE@%%@EH@%%@NL@%
  15019. %@NL@%
  15020. To make C programs portable, you must examine two aspects of your code:
  15021. hardware assumptions and compiler dependency. This section deals with
  15022. hardware assumptions. Section 13.2, "Assumptions about the Compiler," deals
  15023. with compiler dependency.  %@NL@%
  15024. %@NL@%
  15025. %@NL@%
  15026. %@3@%%@CR:C6A00130003 @%%@AB@%13.1.1  Size of Basic Types%@AE@%%@EH@%%@NL@%
  15027. %@NL@%
  15028. In C, the size of basic types (%@AB@%char%@AE@%, %@AB@%signed%@AE@% %@AB@%int%@AE@%, %@AB@%unsigned int%@AE@%, %@AB@%float%@AE@%,
  15029. %@AB@%double%@AE@%, and %@AB@%long double%@AE@%) is implementation-defined, so relying on a
  15030. particular data type to be a given size reduces the portability of a
  15031. program.  %@NL@%
  15032. %@NL@%
  15033. %@AU@% Don't make assumptions about the size of data types.%@AE@%  %@NL@%
  15034. %@NL@%
  15035. Because the size of basic types is left to the implementation, do not make
  15036. assumptions about the size or alignment of data types within aggregate
  15037. types. Use only the %@AB@%sizeof %@AE@%operator to determine the size or amount of
  15038. storage required for a variable or a type.  %@NL@%
  15039. %@NL@%
  15040. Following are some rules governing the size of data types.  %@NL@%
  15041. %@NL@%
  15042. %@NL@%
  15043. %@4@%%@AB@%Type char%@AE@%%@EH@%%@NL@%
  15044. %@NL@%
  15045. Type %@AB@%char%@AE@% is the smallest of the basic types, but it must be large enough to
  15046. hold any of the characters in the implementation's basic character set.
  15047. Normally, variables of type %@AB@%char%@AE@% are one byte.  %@NL@%
  15048. %@NL@%
  15049. %@NL@%
  15050. %@4@%%@AB@%Type int and Type short int%@AE@%%@EH@%%@NL@%
  15051. %@NL@%
  15052. Type %@AB@%int%@AE@% and type %@AB@%short int%@AE@% often correspond to the register size of the
  15053. target machine. Both %@AB@%int%@AE@% and %@AB@%short%@AE@% are greater than or equal to the size of
  15054. type %@AB@%char%@AE@% but less than or equal to the size of type %@AB@%long%@AE@%.  %@NL@%
  15055. %@NL@%
  15056. If you assume that type %@AB@%int%@AE@% is a certain size, your code may not be portable
  15057. because  %@NL@%
  15058. %@NL@%
  15059. %@NL@%
  15060.   ■   An %@AB@%int%@AE@% can be defined as a 16-bit (two-byte) or a 32-bit quantity.%@NL@%
  15061. %@NL@%
  15062.   ■   An %@AB@%int%@AE@% is not always large enough to hold array indexes. For large
  15063.       arrays, you must use %@AB@%unsigned int%@AE@%; for extremely large arrays, use
  15064.       %@AB@%long%@AE@%. To be certain your code is portable, define your array indexes
  15065.       as type %@AB@%size_t%@AE@%. You may not know, before porting your code, the
  15066.       maximum value to expect an array index of type %@AB@%int%@AE@% to hold. The file
  15067.       LIMITS.H contains manifest constants, listed below, for the maximum
  15068.       and minimum values of each basic integral type.%@NL@%
  15069. %@NL@%
  15070. %@NL@%
  15071. %@AB@%Constant%@AE@%                          %@AB@%Value%@AE@%
  15072. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15073. %@AB@%CHAR_BIT%@AE@%                          Number of bits in a variable of type %@AB@%%@AE@%
  15074.                                   %@AB@%char%@AE@%
  15075.  
  15076. %@AB@%CHAR_MIN%@AE@%                          Minimum value a variable of type %@AB@%char%@AE@% 
  15077.                                   can hold
  15078.  
  15079. %@AB@%CHAR_MAX%@AE@%                          Maximum value a variable of type %@AB@%char%@AE@% 
  15080.                                   can hold
  15081.  
  15082. %@AB@%SCHAR_MIN%@AE@%                         Minimum value a variable of type %@AB@%signed%@AE@% %@AB@%%@AE@%
  15083.                                   %@AB@%char%@AE@%
  15084.                                   can hold
  15085.  
  15086. %@AB@%SCHAR_MAX%@AE@%                         Maximum value a variable of type %@AB@%signed%@AE@% %@AB@%%@AE@%
  15087.                                   %@AB@%char%@AE@%
  15088.                                   can hold
  15089.  
  15090. %@AB@%UCHAR_MAX%@AE@%                         Maximum value a variable of type %@AB@%%@AE@%
  15091.                                   %@AB@%unsigned%@AE@% %@AB@%char%@AE@% can hold
  15092.  
  15093. %@AB@%SHRT_MIN%@AE@%                          Minimum value a variable of type %@AB@%short%@AE@% 
  15094.                                   can hold
  15095.  
  15096. %@AB@%SHRT_MAX%@AE@%                          Maximum value a variable of type %@AB@%short%@AE@% 
  15097.                                   can hold
  15098.  
  15099. %@AB@%USHRT_MAX%@AE@%                         Maximum value a variable of type %@AB@%%@AE@%
  15100.                                   %@AB@%unsigned short%@AE@% can hold
  15101.  
  15102. %@AB@%INT_MIN%@AE@%                           Minimum value a variable of type %@AB@%int%@AE@% can
  15103.                                   hold
  15104.  
  15105. %@AB@%INT_MAX%@AE@%                           Maximum value a variable of type %@AB@%int%@AE@% can
  15106.                                   hold
  15107.  
  15108. %@AB@%UINT_MAX%@AE@%                          Maximum value a variable of type %@AB@%%@AE@%
  15109.                                   %@AB@%unsigned int%@AE@%
  15110.                                   can hold
  15111.  
  15112. %@AB@%LONG_MIN%@AE@%                          Minimum value a variable of type %@AB@%long%@AE@% 
  15113.                                   can hold
  15114.  
  15115. %@AB@%LONG_MAX%@AE@%                          Maximum value a variable of type %@AB@%long%@AE@% 
  15116.                                   can hold
  15117.  
  15118. %@AB@%ULONG_MAX%@AE@%                         Maximum value a variable of type %@AB@%%@AE@%
  15119.                                   %@AB@%unsigned long%@AE@% can hold
  15120.  
  15121. %@NL@%
  15122. %@4@%%@AB@%Type float, Type double, and Type long double%@AE@%%@EH@%%@NL@%
  15123. %@NL@%
  15124. Type %@AB@%float%@AE@% is the smallest of the basic floating-point types. Type %@AB@%double%@AE@% is
  15125. usually larger than type %@AB@%float%@AE@%, and type %@AB@%long double%@AE@% is usually the largest
  15126. of the floating-point types. You can make only these portability assumptions
  15127. about floating-point types:  %@NL@%
  15128. %@NL@%
  15129. %@NL@%
  15130.   ■   Any value that can be represented as type %@AB@%float%@AE@% can be represented as
  15131.       type %@AB@%double%@AE@% (type %@AB@%float%@AE@% is a subset of type %@AB@%double%@AE@%).%@NL@%
  15132. %@NL@%
  15133.   ■   Any value that can be represented as type %@AB@%double%@AE@% can be represented as
  15134.       type %@AB@%long double%@AE@% (type %@AB@%double%@AE@% is a subset of type %@AB@%long double%@AE@%).%@NL@%
  15135. %@NL@%
  15136. %@NL@%
  15137. The file FLOAT.H contains manifest constants, listed below, for the maximum
  15138. and minimum values of each basic floating-point type.  %@NL@%
  15139. %@NL@%
  15140. %@AB@%Constant%@AE@%                          %@AB@%Value%@AE@%
  15141. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15142. %@AB@%DBL_DIG%@AE@%                           Number of decimal digits of precision a 
  15143.                                   variable of type %@AB@%double%@AE@% can hold
  15144.  
  15145. %@AB@%DBL_MAX%@AE@%                           Maximum value a variable of type %@AB@%double%@AE@% 
  15146.                                   can hold
  15147.  
  15148. %@AB@%DBL_MAX_10_EXP%@AE@%                    Maximum value (base 10) the exponent of 
  15149.                                   a variable of type %@AB@%double%@AE@% can hold
  15150.  
  15151. %@AB@%DBL_MAX_EXP%@AE@%                       Maximum value (base 2) the exponent of a
  15152.                                   variable of type %@AB@%double%@AE@% can hold
  15153.  
  15154. %@AB@%DBL_MIN%@AE@%                           Minimum positive value a variable of 
  15155.                                   type %@AB@%double%@AE@% can hold
  15156.  
  15157. %@AB@%DBL_MIN_10_EXP%@AE@%                    Minimum value (base 10) the exponent of 
  15158.                                   a variable of type %@AB@%double%@AE@% can hold
  15159.  
  15160. %@AB@%DBL_MIN_EXP%@AE@%                       Minimum value (base 2) the exponent of a
  15161.                                   variable of type %@AB@%double%@AE@% can hold
  15162.  
  15163. %@AB@%FLT_DIG%@AE@%                           Number of decimal digits of precision a 
  15164.                                   variable of type %@AB@%float%@AE@% can hold
  15165.  
  15166. %@AB@%FLT_MAX%@AE@%                           Maximum value a variable of type %@AB@%float%@AE@% 
  15167.                                   can hold
  15168.  
  15169. %@AB@%FLT_MAX_10_EXP%@AE@%                    Maximum value (base 10) the exponent of 
  15170.                                   a variable of type %@AB@%float%@AE@% can hold
  15171.  
  15172. %@AB@%FLT_MAX_EXP%@AE@%                       Maximum value (base 2) the exponent of a
  15173.                                   variable of type %@AB@%float%@AE@% can hold
  15174.  
  15175. %@AB@%FLT_MIN%@AE@%                           Minimum positive value a variable of 
  15176.                                   type %@AB@%float%@AE@% can hold
  15177.  
  15178. %@AB@%FLT_MIN_10_EXP%@AE@%                    Minimum value (base 10) the exponent of 
  15179.                                   a variable of type %@AB@%float%@AE@% can hold
  15180.  
  15181. %@AB@%FLT_MIN_EXP%@AE@%                       Minimum value (base 2) the exponent of a
  15182.                                   variable of type %@AB@%float%@AE@% can hold
  15183.  
  15184. %@AB@%LDBL_DIG%@AE@%                          Number of decimal digits of precision a 
  15185.                                   variable of type %@AB@%long double%@AE@% can hold
  15186.  
  15187. %@AB@%LDBL_MAX%@AE@%                          Maximum value a variable of type %@AB@%long %@AE@%
  15188.                                   %@AB@%double%@AE@% can hold
  15189.  
  15190. %@AB@%LDBL_MAX_10_EXP%@AE@%                   Maximum value (base 10) the exponent of 
  15191.                                   a variable of type %@AB@%long double%@AE@% can hold
  15192.  
  15193. %@AB@%LDBL_MAX_EXP%@AE@%                      Maximum value (base 2) the exponent of a
  15194.                                   variable of type %@AB@%long double%@AE@% can hold
  15195.  
  15196. %@AB@%LDBL_MIN%@AE@%                          Minimum positive value a variable of 
  15197.                                   type %@AB@%long double%@AE@% can hold
  15198.  
  15199. %@AB@%LDBL_MIN_10_EXP%@AE@%                   Minimum value (base 10) the exponent of 
  15200.                                   a variable of type %@AB@%long double%@AE@% can hold
  15201.  
  15202. %@AB@%LDBL_MIN_EXP%@AE@%                      Minimum value (base 2) the exponent of a
  15203.                                   variable of type %@AB@%long double%@AE@% can hold
  15204.  
  15205. %@NL@%
  15206. %@4@%%@AB@%Microsoft C Type Sizes%@AE@%%@EH@%%@NL@%
  15207. %@NL@%
  15208. Table 13.1 summarizes the size of the basic types in Microsoft C.  %@NL@%
  15209. %@NL@%
  15210. %@AB@%Table 13.1  %@AB@%Size of Basic Types in Microsoft C%@AE@%%@AE@%
  15211.  
  15212. %@TH:  22   848 03 38 38 @%
  15213.                                       Number 
  15214. Type                                  of Bytes
  15215. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15216. %@AB@%char%@AE@%, %@AB@%unsigned char%@AE@%                   1
  15217.  
  15218. %@AB@%int%@AE@%, %@AB@%short%@AE@%,%@AB@% unsigned int%@AE@%,%@AB@%%@AE@%             2
  15219. %@AB@%unsigned short%@AE@%                        
  15220.  
  15221. %@AB@%near pointer%@AE@%                          2
  15222.  
  15223. %@AB@%long%@AE@%, %@AB@%unsigned long%@AE@%                   4
  15224.  
  15225. %@AB@%far pointer%@AE@%                           4
  15226.  
  15227. %@AB@%float%@AE@%                                 4
  15228.  
  15229. %@AB@%double%@AE@%                                8
  15230.  
  15231. %@AB@%long double%@AE@%                           10
  15232.  
  15233. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15234.  
  15235. %@TE:  22   848 03 38 38 @%
  15236.  
  15237. %@NL@%
  15238. %@3@%%@CR:C6A00130004 @%%@AB@%13.1.2  Storage Order and Alignment%@AE@%%@EH@%%@NL@%
  15239. %@NL@%
  15240. The C language does not define any specific layout for the storage of data
  15241. items relative to one another. The layout for storage of structure elements,
  15242. or unions within a structure or union, is defined by the implementation.  %@NL@%
  15243. %@NL@%
  15244. Some processors require that data longer than one byte be word-aligned
  15245. (aligned to an even-byte address). Other processors, such as the 80%@AI@%x%@AE@%86
  15246. family, do not have such a restriction.  %@NL@%
  15247. %@NL@%
  15248. %@NL@%
  15249. %@4@%%@AB@%Structure Order and Alignment%@AE@%%@EH@%%@NL@%
  15250. %@NL@%
  15251. The example below illustrates how alignment can affect your program. In the
  15252. example, a structure is cast to type %@AB@%long%@AE@% because the programmer knew the
  15253. order in which a particular implementation stored data.  %@NL@%
  15254. %@NL@%
  15255. %@AS@%  /* Nonportable code */
  15256. %@AS@%  struct time
  15257. %@AS@%  {
  15258. %@AS@%      char hour;     /* 0 < hour < 24   -- fits in a char */
  15259. %@AS@%      char minute;   /* 0 < minute < 60 -- fits in a char */
  15260. %@AS@%      char second;   /* 0 < second < 60 -- fits in a char */
  15261. %@AS@%  };
  15262. %@AS@%  
  15263. %@AS@%      .
  15264. %@AS@%      .
  15265. %@AS@%      .
  15266. %@AS@%      struct time now, alarm_time;
  15267. %@AS@%      .
  15268. %@AS@%      .
  15269. %@AS@%      .
  15270. %@AS@%      if ( (long)now >= (long)alarm_time )
  15271. %@AS@%      {
  15272. %@AS@%          /* sound an alarm */
  15273. %@AS@%      }%@AE@%%@NL@%
  15274. %@NL@%
  15275. The preceding code makes these nonportable assumptions:  %@NL@%
  15276. %@NL@%
  15277. %@NL@%
  15278.   ■   The data for %@AS@% hour %@AE@% will be stored in a higher order position than %@AS@%
  15279. %@AS@%      minute %@AE@% or %@AS@% second%@AE@%. Because C does not guarantee storage order or
  15280.       alignment of structures or unions, the code may not be portable to
  15281.       other machines.%@NL@%
  15282. %@NL@%
  15283.   ■   Three variables of type %@AB@%char %@AE@%will be shorter than or the same length
  15284.       as a variable of type %@AB@%long%@AE@%. Thus, the code is not portable according
  15285.       to the rules governing the size of basic types, as described in
  15286.       Section 13.1.1.%@NL@%
  15287. %@NL@%
  15288. %@NL@%
  15289. If either of these assumptions proves false, the comparison (%@AB@%if %@AE@%statement)
  15290. is invalid.  %@NL@%
  15291. %@NL@%
  15292. %@AU@% You can write code that makes no assumptions about storage order.%@AE@%  %@NL@%
  15293. %@NL@%
  15294. To make the program in the preceding example portable, you can break the
  15295. comparison between the two long integers into a component-by-component
  15296. comparison. This technique is illustrated in the following example:  %@NL@%
  15297. %@NL@%
  15298. %@AS@%  /* Portable code */
  15299. %@AS@%  struct time
  15300. %@AS@%  {
  15301. %@AS@%      char hour;     /* 0 < hour < 24   -- fits in a char */
  15302. %@AS@%      char minute;   /* 0 < minute < 60 -- fits in a char */
  15303. %@AS@%      char second;   /* 0 < second < 60 -- fits in a char */
  15304. %@AS@%  };
  15305. %@AS@%  
  15306. %@AS@%      .
  15307. %@AS@%      .
  15308. %@AS@%      .
  15309. %@AS@%      struct time now, alarm_time;
  15310. %@AS@%      .
  15311. %@AS@%      .
  15312. %@AS@%      .
  15313. %@AS@%      if ( time_cmp( now, alarm_time ) >= 0 )
  15314. %@AS@%      {
  15315. %@AS@%          /* sound an alarm */
  15316. %@AS@%      }
  15317. %@AS@%      .
  15318. %@AS@%      .
  15319. %@AS@%      .
  15320. %@AS@%  
  15321. %@AS@%  int time_cmp( struct time t1, struct time t2 )
  15322. %@AS@%  {
  15323. %@AS@%      if( t1.hour != t2.hour )
  15324. %@AS@%          return( t2.hour - t1.hour );
  15325. %@AS@%      if( t1.minute != t2.minute )
  15326. %@AS@%          return( t2.minute - t1.minute );
  15327. %@AS@%      return( t2.second - t1.second );
  15328. %@AS@%  }%@AE@%%@NL@%
  15329. %@NL@%
  15330. %@NL@%
  15331. %@4@%%@AB@%Union Order and Alignment%@AE@%%@EH@%%@NL@%
  15332. %@NL@%
  15333. Programmers use unions most often for two purposes: to store data whose
  15334. exact type is not known until run time or to access the same data in
  15335. different ways.  %@NL@%
  15336. %@NL@%
  15337. Unions falling into the second category are usually not portable. For
  15338. example, the union below is not portable:  %@NL@%
  15339. %@NL@%
  15340. %@AS@%  union tag_u
  15341. %@AS@%  {
  15342. %@AS@%   char bytes_in_long[4];
  15343. %@AS@%   long a_long;
  15344. %@AS@%  };%@AE@%%@NL@%
  15345. %@NL@%
  15346. The intent of the union above is to access the individual bytes of a
  15347. variable of type %@AB@%long%@AE@%. However, the union may not work as intended when
  15348. ported to other computers because  %@NL@%
  15349. %@NL@%
  15350. %@NL@%
  15351.   ■   It relies on a constant size for type %@AB@%long%@AE@%.%@NL@%
  15352. %@NL@%
  15353.   ■   It may assume byte ordering within a variable of type %@AB@%long%@AE@%. (Byte
  15354.       ordering is described in detail in Section 13.1.3, "Byte Order in a
  15355.       Word.")%@NL@%
  15356. %@NL@%
  15357. %@NL@%
  15358. The first problem can be addressed by coding the union as follows:  %@NL@%
  15359. %@NL@%
  15360. %@AS@%  union tag_u 
  15361. %@AS@%  {
  15362. %@AS@%   char bytes_in_long[sizeof( long ) / sizeof( char )];
  15363. %@AS@%   long a_long;
  15364. %@AS@%  };%@AE@%%@NL@%
  15365. %@NL@%
  15366. Note the use of the %@AB@%sizeof%@AE@% operator to determine the size of a data type.  %@NL@%
  15367. %@NL@%
  15368. %@NL@%
  15369. %@3@%%@CR:C6A00130005 @%%@AB@%13.1.3  Byte Order in a Word%@AE@%%@EH@%%@NL@%
  15370. %@NL@%
  15371. The order of bytes within a word (%@AB@%int %@AE@%or %@AB@%short%@AE@%) or a double word (%@AB@%long%@AE@%) can
  15372. vary among machines. Code that assumes an internal order is not portable, as
  15373. shown by this example:  %@NL@%
  15374. %@NL@%
  15375. %@AS@%  /*
  15376. %@AS@%   * Nonportable structure to access an
  15377. %@AS@%   * int in bytes.
  15378. %@AS@%   */
  15379. %@AS@%  struct tag_int_bytes
  15380. %@AS@%  {
  15381. %@AS@%      char lobyte;
  15382. %@AS@%      char hibyte;
  15383. %@AS@%  };%@AE@%%@NL@%
  15384. %@NL@%
  15385. A more portable way to access the individual bytes in a word is to define
  15386. two macros that rely on the constant %@AB@%CHAR_BIT%@AE@%, defined in LIMITS.H:  %@NL@%
  15387. %@NL@%
  15388. %@AS@%  #define LOBYTE(a) (char)((a) & 0xff)
  15389. %@AS@%  #define HIBYTE(a) (char)((unsigned)(a) >> CHAR_BIT)%@AE@%%@NL@%
  15390. %@NL@%
  15391. The %@AB@%LOBYTE%@AE@% macro is still not completely portable. It assumes that a %@AB@%char %@AE@%is
  15392. eight bits long, and it uses the constant %@AS@% 0xff %@AE@% to mask the high-order
  15393. eight bits. Because portable programs cannot rely on a given number of bits
  15394. in a byte, consider the revision below:  %@NL@%
  15395. %@NL@%
  15396. %@AS@%  #define LOBYTE(a) (char)((a) & ((unsigned)~0>>CHAR_BIT))
  15397. %@AS@%  #define HIBYTE(a) (char)((unsigned)(a) >> CHAR_BIT)%@AE@%%@NL@%
  15398. %@NL@%
  15399. The new %@AB@%LOBYTE %@AE@%macro performs a bitwise complement on 0; that is, all zero
  15400. bits are turned into ones. It then takes that unsigned quantity and shifts
  15401. it right far enough to create a mask of the correct length for the
  15402. implementation.  %@NL@%
  15403. %@NL@%
  15404. The following code assumes that the order of bytes in a word will be
  15405. leastsignificant first:  %@NL@%
  15406. %@NL@%
  15407. %@AS@%  int c;
  15408. %@AS@%      .
  15409. %@AS@%      .
  15410. %@AS@%      .
  15411. %@AS@%      fread( &c, sizeof( char ), 1, fp );%@AE@%%@NL@%
  15412. %@NL@%
  15413. The code attempts to read one byte as an %@AB@%int%@AE@%, without converting it from a
  15414. %@AB@%char%@AE@%. However, the code will fail in any implementation where the low-order
  15415. byte is not the first byte of an %@AB@%int%@AE@%. The following solution is more
  15416. portable. In the example below, the data is read into an intermediate
  15417. variable of type %@AB@%char%@AE@% before being assigned to the integer variable.  %@NL@%
  15418. %@NL@%
  15419. %@AS@%  int c;
  15420. %@AS@%      char ch;
  15421. %@AS@%      .
  15422. %@AS@%      .
  15423. %@AS@%      .
  15424. %@AS@%      fread( &ch, sizeof( char ), 1, fp );
  15425. %@AS@%      c = ch;%@AE@%%@NL@%
  15426. %@NL@%
  15427. The example below shows how to use the C run-time function %@AB@%fgetc%@AE@% to return
  15428. the value. The %@AB@%fgetc%@AE@% function returns type %@AB@%char%@AE@%, but the value is promoted
  15429. to type %@AB@%int%@AE@% when it is assigned to a variable of type %@AB@%int%@AE@%.  %@NL@%
  15430. %@NL@%
  15431. %@AS@%  int c;
  15432. %@AS@%      .
  15433. %@AS@%      .
  15434. %@AS@%      .
  15435. %@AS@%      c = fgetc( fp );%@AE@%%@NL@%
  15436. %@NL@%
  15437. %@NL@%
  15438. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15439. %@NL@%
  15440. Microsoft C normally aligns data types longer than one byte to an even-byte
  15441. address for improved performance. See the /Zp compiler option and the %@AB@%pack%@AE@%
  15442. pragma in the %@AI@%Microsoft C Reference%@AE@% and in on-line help for information
  15443. about controlling structure packing in Microsoft C.  %@NL@%
  15444. %@NL@%
  15445. %@NL@%
  15446. %@3@%%@CR:C6A00130006 @%%@AB@%13.1.4  Reading and Writing Structures%@AE@%%@EH@%%@NL@%
  15447. %@NL@%
  15448. Many C programs read data from disk into structures and write data to disk
  15449. from structures. The functions that perform disk I/O in C require you to
  15450. specify the number of bytes to be transferred. You should always use the
  15451. %@AB@%sizeof%@AE@% operator to obtain the size of the data to be read or written because
  15452. differing data type sizes or alignment schemes may alter the size of a given
  15453. structure. For example,  %@NL@%
  15454. %@NL@%
  15455. %@AS@%  fread( &my_struct, sizeof(my_struct), 1, fp );%@AE@%%@NL@%
  15456. %@NL@%
  15457. %@NL@%
  15458. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15459. %@NL@%
  15460. When performing disk input and output in Microsoft C, structures may be
  15461. different sizes depending on the structure-packing option you have selected
  15462. (see the /Zp compiler option and the %@AB@%pack%@AE@% pragma in the %@AI@%Microsoft C
  15463. %@AI@%Reference%@AE@%).  %@NL@%
  15464. %@NL@%
  15465. %@NL@%
  15466. %@3@%%@CR:C6A00130007 @%%@AB@%13.1.5  Bit Fields in Structures%@AE@%%@EH@%%@NL@%
  15467. %@NL@%
  15468. The Microsoft C compiler implements bit fields. However, many C compilers
  15469. do not.  %@NL@%
  15470. %@NL@%
  15471. Bit fields allow you to access the individual bits within a data item. While
  15472. the practice of accessing the bits in a data item is inherently nonportable,
  15473. you can  %@NL@%
  15474. %@NL@%
  15475. improve your chances of porting a program that uses bit fields if you make
  15476. no assumptions about order of assignment, or size and alignment of bit
  15477. fields.  %@NL@%
  15478. %@NL@%
  15479. %@NL@%
  15480. %@4@%%@AB@%Order of Assignment%@AE@%%@EH@%%@NL@%
  15481. %@NL@%
  15482. The order of assignment of bit fields in memory is left to the
  15483. implementation, so you cannot rely on a particular entry in a bit field
  15484. structure to be in a higher order position than another. (This problem is
  15485. similar to the portability constraint imposed by alignment of basic data
  15486. types in structures. The C language does not define any specific layout for
  15487. the storage of data items relative to one another.) See Section 13.1.2,
  15488. "Storage Order and Alignment" for more information.  %@NL@%
  15489. %@NL@%
  15490. %@NL@%
  15491. %@4@%%@AB@%Size and Alignment of Bit Fields%@AE@%%@EH@%%@NL@%
  15492. %@NL@%
  15493. The Microsoft C compiler supports bit fields up to the size of the type
  15494. %@AB@%long%@AE@%. Each individual member of the bit field structure can be up to the
  15495. size of the declared type. Some compilers do not support bit field-structure
  15496. elements that are longer than type %@AB@%int%@AE@%.  %@NL@%
  15497. %@NL@%
  15498. The example below defines a bit field, %@AS@% short_bitfield%@AE@%, that is shorter than
  15499. type %@AB@%int%@AE@%:  %@NL@%
  15500. %@NL@%
  15501. %@AS@%  struct short_bitfield
  15502. %@AS@%  {
  15503. %@AS@%      unsigned usr_bkup : 1; /* 0  <= usr_bkup <  1 */
  15504. %@AS@%      unsigned usr_sec  : 4; /* 9 <= usr_sec < 16 */
  15505. %@AS@%  };%@AE@%%@NL@%
  15506. %@NL@%
  15507. The example below defines a bit field, %@AS@% long_bitfield%@AE@%, that has elements
  15508. longer than type %@AB@%int%@AE@%:  %@NL@%
  15509. %@NL@%
  15510. %@AS@%  struct long_bitfield
  15511. %@AS@%  {
  15512. %@AS@%      unsigned long disk_pos : 22;  /* 0 <= disk_pos   < 4,194,304 */
  15513. %@AS@%      unsigned long rec_no   : 10;  /* 0 <= rec_no < 1,024 */
  15514. %@AS@%  };%@AE@%%@NL@%
  15515. %@NL@%
  15516. The bit field %@AS@% short_bitfield %@AE@% is likely to be supported by more
  15517. implementations than %@AS@% long_bitfield%@AE@%.  %@NL@%
  15518. %@NL@%
  15519. %@NL@%
  15520. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15521. %@NL@%
  15522. The example below introduces another portability issue: alignment of data
  15523. defined in bit fields. The Microsoft C compiler does not allow an element in
  15524. a structure to extend across two words. The first two elements, %@AS@% day %@AE@% and %@AS@%
  15525. %@AS@%month%@AE@%, take up nine bits. The third, %@AS@% year%@AE@%, would extend across a word
  15526. boundary, so it must begin on the next word boundary.  %@NL@%
  15527. %@NL@%
  15528. %@AS@%  struct long_bitfield
  15529. %@AS@%  {
  15530. %@AS@%      unsigned int day    : 5;  /* 0 <= day   < 32 */
  15531. %@AS@%      unsigned int month  : 4;  /* 0 <= month < 16 */
  15532. %@AS@%      unsigned int year   : 11; /* 0 <= year  < 2048 */
  15533. %@AS@%  };%@AE@%%@NL@%
  15534. %@NL@%
  15535. Figure 13.1 illustrates the example above.  %@NL@%
  15536. %@NL@%
  15537. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  15538. %@NL@%
  15539. Other compilers may not use the same storage techniques.  %@NL@%
  15540. %@NL@%
  15541. %@NL@%
  15542. %@3@%%@CR:C6A00130008 @%%@AB@%13.1.6  Processor Arithmetic Mode%@AE@%%@EH@%%@NL@%
  15543. %@NL@%
  15544. Two types of arithmetic are common on digital computers: one's-complement
  15545. arithmetic and two's-complement arithmetic. Some programs assume that all
  15546. target computers perform two's-complement arithmetic. If you take advantage
  15547. of the fact that a given operation causes a particular bit pattern to be set
  15548. on either a one's-complement or two's-complement computer, your program will
  15549. not be portable. For example, two's-complement machines represent the
  15550. eight-bit integer value -1 as a binary 11111111. A one's-complement machine
  15551. represents the same decimal value (-1) as 11111110. Some programmers assume
  15552. that -1 will fill a byte or a word with ones, and use it to construct a mask
  15553. template that they later shift. This will not work correctly on
  15554. one's-complement machines, but the error will not surface until the
  15555. least-significant bit is used.  %@NL@%
  15556. %@NL@%
  15557. In two's-complement arithmetic, there is only one value that represents
  15558. zero. In one's-complement arithmetic, there is a value for zero and a value
  15559. for negative zero. Use the C relational operators to handle this anomaly
  15560. correctly; if you write code that deliberately circumvents the C relational
  15561. operators, tests for zero or %@AB@%NULL %@AE@%may not operate correctly.  %@NL@%
  15562. %@NL@%
  15563. %@NL@%
  15564. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15565. %@NL@%
  15566. Microsoft C produces code only for the Intel 80%@AI@%x%@AE@%86 processors, which all
  15567. perform two's-complement arithmetic.  %@NL@%
  15568. %@NL@%
  15569. %@NL@%
  15570. %@3@%%@CR:C6A00130009 @%%@AB@%13.1.7  Pointers%@AE@%%@EH@%%@NL@%
  15571. %@NL@%
  15572. One of the most powerful but potentially dangerous features of the C
  15573. language is its use of indirect addressing through pointers. Bugs introduced
  15574. by misusing pointers can be difficult to detect and isolate because the
  15575. error often corrupts memory unpredictably.  %@NL@%
  15576. %@NL@%
  15577. %@NL@%
  15578. %@4@%%@AB@%Casting Pointers%@AE@%%@EH@%%@NL@%
  15579. %@NL@%
  15580. Be sure you do not make nonportable assumptions when casting pointers to
  15581. different types.  %@NL@%
  15582. %@NL@%
  15583. %@AS@%  /* Nonportable coercion */
  15584. %@AS@%  char c[4];
  15585. %@AS@%  long *lp;
  15586. %@AS@%  
  15587. %@AS@%  lp = (long *)c;
  15588. %@AS@%  *lp = 0x12345678L;%@AE@%%@NL@%
  15589. %@NL@%
  15590. This code is nonportable because using a cast to change an array of %@AB@%char%@AE@% to
  15591. a pointer of type %@AB@%long%@AE@% assumes a particular byte-ordering scheme. This is
  15592. discussed in greater detail in Section 13.1.3, "Byte Order in a Word."  %@NL@%
  15593. %@NL@%
  15594. %@NL@%
  15595. %@4@%%@AB@%Pointer Size%@AE@%%@EH@%%@NL@%
  15596. %@NL@%
  15597. A pointer can be assigned (or cast) to any integer type large enough to hold
  15598. it, but the size of the integer type depends on the machine and the
  15599. implementation. (In fact, it can even depend on the memory model.)
  15600. Therefore, you cannot assume:  %@NL@%
  15601. %@NL@%
  15602. %@AS@%  sizeof( char * ) == sizeof( int )%@AE@%%@NL@%
  15603. %@NL@%
  15604. To determine the size of any unmodified data pointer, use  %@NL@%
  15605. %@NL@%
  15606. %@AS@%  sizeof( void * )%@AE@%%@NL@%
  15607. %@NL@%
  15608. the size of a generic data pointer.  %@NL@%
  15609. %@NL@%
  15610. %@NL@%
  15611. %@4@%%@AB@%Pointer Subtraction%@AE@%%@EH@%%@NL@%
  15612. %@NL@%
  15613. Code that assumes that pointer subtraction yields an %@AB@%int%@AE@% value is
  15614. nonportable. Pointer subtraction yields a result of type %@AB@%ptrdiff_t%@AE@% (defined
  15615. in STDDEF.H). Portable code must always use variables of type %@AB@%ptrdiff_t%@AE@% for
  15616. storing the result of pointer subtraction.  %@NL@%
  15617. %@NL@%
  15618. %@NL@%
  15619. %@4@%%@AB@%The Null Pointer%@AE@%%@EH@%%@NL@%
  15620. %@NL@%
  15621. In most implementations, %@AB@%NULL%@AE@% is defined as 0. In Microsoft C, it is defined
  15622. as %@AS@% ((void *)0)%@AE@%. Because code pointers and data pointers are often different
  15623. sizes, using 0 for the null pointer for both can lead to nonportability. The
  15624. difference in size between code pointers and data pointers will cause
  15625. problems for functions that expect pointer arguments longer than an %@AB@%int%@AE@%. To
  15626. avoid these problems, use the null pointer, as defined in the include file
  15627. STDDEF.H; use prototypes; or explicitly cast %@AB@%NULL %@AE@%to the correct data type.
  15628. Here is a portable way to use the null pointer:  %@NL@%
  15629. %@NL@%
  15630. %@AS@%  /* Portable use of the NULL pointer */
  15631. %@AS@%  main()
  15632. %@AS@%  {
  15633. %@AS@%      func1( (char *)NULL );
  15634. %@AS@%      func2( (void *(*)())NULL );
  15635. %@AS@%  }
  15636. %@AS@%  
  15637. %@AS@%  void func1( char * c )
  15638. %@AS@%  {
  15639. %@AS@%  }
  15640. %@AS@%  
  15641. %@AS@%  void func2( void *(* func)() )
  15642. %@AS@%  {
  15643. %@AS@%  }%@AE@%%@NL@%
  15644. %@NL@%
  15645. The invocations of %@AS@% func1 %@AE@% and %@AS@% func2 %@AE@% explicitly cast %@AB@%NULL %@AE@%to the correct
  15646. size. In the case of %@AS@% func1%@AE@%, %@AB@%NULL %@AE@%is cast to type %@AB@%char *%@AE@%; in the case of %@AS@%
  15647. %@AS@%func2%@AE@%, it is cast to a pointer to a function that returns type %@AB@%void%@AE@%.  %@NL@%
  15648. %@NL@%
  15649. %@NL@%
  15650. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15651. %@NL@%
  15652. Subtraction of pointers to huge arrays that have more than 32,767 elements
  15653. may yield a %@AB@%long%@AE@% result. The %@AB@%_huge%@AE@% keyword is implementation-defined by
  15654. Microsoft C and is not portable. Here is how to subtract pointers to huge
  15655. arrays:%@CR:C6A00130010 @%  %@NL@%
  15656. %@NL@%
  15657. %@AS@%  char _huge *a;
  15658. %@AS@%  char _huge *b;
  15659. %@AS@%  long        d;
  15660. %@AS@%  .
  15661. %@AS@%  .
  15662. %@AS@%  .
  15663. %@AS@%  d = (long)( a - b );%@AE@%%@NL@%
  15664. %@NL@%
  15665. In Microsoft C, the memory model selected and the special keywords %@AB@%_near%@AE@%,
  15666. %@AB@%_far%@AE@%, and %@AB@%_huge %@AE@%can change the size of a pointer. The Microsoft memory
  15667. models and extended keywords are nonportable, but you should be aware of
  15668. their effects.%@CR:C6A00130011 @%%@CR:C6A00130012 @%%@CR:C6A00130013 @%  %@NL@%
  15669. %@NL@%
  15670. Sizes of generic pointers and default pointer sizes are shown in Tables 13.2
  15671. and 13.3, respectively.  %@NL@%
  15672. %@NL@%
  15673. %@AB@%Table 13.2  %@AB@%Size of Generic Pointers%@AE@%%@AE@%
  15674.  
  15675. %@TH:   6   438 02 15 23 38 @%
  15676. Declaration    Name                   Size
  15677. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15678. %@AB@%void _near *%@AE@%   Generic near pointer   16 bits
  15679. %@AB@%void _far *%@AE@%    Generic far pointer    32 bits
  15680. %@AB@%void _huge *%@AE@%   Generic huge pointer   32 bits
  15681. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15682. %@TE:   6   438 02 15 23 38 @%
  15683.  
  15684. %@AB@%Table 13.3  %@AB@%Default Pointer Sizes%@AE@%%@AE@%
  15685.  
  15686. %@TH:   9   518 02 14 19 43 @%
  15687. Memory Model  Code Pointer Size  Data Pointer Size
  15688. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15689. Tiny          16 bits            16 bits
  15690. Small         16 bits            16 bits
  15691. Medium        32 bits            16 bits
  15692. Compact       16 bits            32 bits
  15693. Large         32 bits            32 bits
  15694. Huge          32 bits            32 bits
  15695. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15696. %@TE:   9   518 02 14 19 43 @%
  15697.  
  15698. %@NL@%
  15699. %@3@%%@CR:C6A00130014 @%%@AB@%13.1.8  Address Space%@AE@%%@EH@%%@NL@%
  15700. %@NL@%
  15701. The amount of available memory and the address space on systems varies,
  15702. depending on many factors outside your control. A program designed with
  15703. portability in mind should handle insufficient-memory situations. To ensure
  15704. that your program handles these situations, you should always check the
  15705. error return from any of the dynamic memory allocation routines, such as
  15706. %@AB@%malloc%@AE@%, %@AB@%calloc%@AE@%, %@AB@%strdup%@AE@%, and %@AB@%realloc%@AE@%.  %@NL@%
  15707. %@NL@%
  15708. These situations occur not only because of a lack of installed memory but
  15709. also because too many other applications are using memory. For example,  %@NL@%
  15710. %@NL@%
  15711. %@NL@%
  15712.   ■   Installed resident software can cause your program to fail. In DOS,
  15713.       these programs are usually device drivers or
  15714.       terminate-and-stay-resident (TSR) utilities.%@NL@%
  15715. %@NL@%
  15716.   ■   An event or combination of events in a multitasking operating system
  15717.       such as OS/2 or XENIX can cause your program to fail. These failures
  15718.       are complex and difficult to predict. Here is an example: the user has
  15719.       installed a daemon to "pop up" every so often and check the system
  15720.       status. The user is running your application along with enough other
  15721.       large applications to cause a critical shortage of memory. When the
  15722.       daemon pops up, your program may fail on a memory allocation request.%@NL@%
  15723. %@NL@%
  15724.   ■   An application running under Windows can use an extraordinary amount
  15725.       of the global heap and not return it to the free pool. This type of
  15726.       behavior will cause Windows to deny a %@AB@%GlobalAlloc%@AE@% request.%@NL@%
  15727. %@NL@%
  15728. %@NL@%
  15729. %@NL@%
  15730. %@3@%%@CR:C6A00130015 @%%@AB@%13.1.9  Character Set%@AE@%%@EH@%%@NL@%
  15731. %@NL@%
  15732. The C language does not define the character set used in an implementation.
  15733. This means that any programs that assume the character set to be ASCII are
  15734. nonportable.  %@NL@%
  15735. %@NL@%
  15736. The only restrictions on the character set are these:  %@NL@%
  15737. %@NL@%
  15738. %@NL@%
  15739.   ■   No character in the implementation's character set may be larger than
  15740.       the size of type %@AB@%char%@AE@%.%@NL@%
  15741. %@NL@%
  15742.   ■   Each character in the set must be represented as a positive value by
  15743.       type %@AB@%char%@AE@%, whether it is treated as signed or unsigned. So, in the
  15744.       case of the ASCII character set and an eight-bit %@AB@%char%@AE@%, the maximum
  15745.       value is 127 (128 is a negative number when stored in a %@AB@%char%@AE@%
  15746.       variable).%@NL@%
  15747. %@NL@%
  15748. %@NL@%
  15749. %@NL@%
  15750. %@4@%%@AB@%Character Classification%@AE@%%@EH@%%@NL@%
  15751. %@NL@%
  15752. The standard C run-time support contains a complete set of
  15753. characterclassification macros and functions. These functions are defined in
  15754. the CTYPE.H file and are guaranteed to be portable:  %@NL@%
  15755. %@NL@%
  15756. %@AB@%isalnum         isdigit         isprint         isupper%@AE@%
  15757. %@AB@%isalpha         isgraph         ispunct         isxdigit%@AE@%
  15758. %@AB@%iscntrl         islower         isspace         
  15759.  
  15760. The following code fragment is not portable to implementations that do not
  15761. use the ASCII character set:  %@NL@%
  15762. %@NL@%
  15763. %@AS@%  /* Nonportable */
  15764. %@AS@%  if( c >= 'A' && c <= 'Z' )
  15765. %@AS@%      /* uppercase alphabetic */%@AE@%%@NL@%
  15766. %@NL@%
  15767. Instead, consider using this:  %@NL@%
  15768. %@NL@%
  15769. %@AS@%  /* Portable */
  15770. %@AS@%  if( isalpha(c) && isupper(c) )
  15771. %@AS@%      /* uppercase alphabetic */%@AE@%%@NL@%
  15772. %@NL@%
  15773. The first example above is nonportable, because it assumes that uppercase %@AS@% A
  15774. %@AS@%%@AE@% is represented by a smaller value than uppercase %@AS@% Z%@AE@%, and that no lowercase
  15775. characters fall between the values of %@AS@% A %@AE@% and %@AS@% Z%@AE@%. The second example is
  15776. portable, because it uses the character classification functions to perform
  15777. the tests.  %@NL@%
  15778. %@NL@%
  15779. In a portable program, you should not perform any comparison on variables of
  15780. type %@AB@%char%@AE@% except strict equality (==). You cannot assume the character set
  15781. follows an increasing sequence─that may not be true on a different machine.
  15782. %@NL@%
  15783. %@NL@%
  15784. %@NL@%
  15785. %@4@%%@AB@%Case Translation%@AE@%%@EH@%%@NL@%
  15786. %@NL@%
  15787. Translation of characters from upper- to lowercase or from lowerto uppercase
  15788. is called "case translation." The following example shows a coding technique
  15789. for case translation not portable to implementations using a non-ASCII
  15790. character set.  %@NL@%
  15791. %@NL@%
  15792. %@AS@%  #define make_upper(c) ((c)&0xcf)
  15793. %@AS@%  #define make_lower(c) ((c)|0x20)%@AE@%%@NL@%
  15794. %@NL@%
  15795. This code takes advantage of the fact that you can map uppercase to
  15796. lowercase simply by changing the state of bit 6. It is extremely efficient
  15797. but nonportable. To write portable code, use the case-translation macros
  15798. %@AB@%toupper%@AE@% and %@AB@%tolower%@AE@% (defined in CTYPE.H).  %@NL@%
  15799. %@NL@%
  15800. %@NL@%
  15801. %@2@%%@CR:C6A00130016 @%%@AB@%13.2  Assumptions about the Compiler%@AE@%%@EH@%%@NL@%
  15802. %@NL@%
  15803. Different compilers translate C source code into object code in different
  15804. ways. The ANSI draft standard for the C programming language defines how
  15805. many of these translations must be done; others are implementation-defined.
  15806. %@NL@%
  15807. %@NL@%
  15808. This section describes assumptions about how the compiler translates your C
  15809. code, which can make your programs nonportable. For a complete description
  15810. of how Microsoft C handles implementation-defined operations, see Appendix
  15811. C, "Implementation-Defined Behavior."  %@NL@%
  15812. %@NL@%
  15813. %@NL@%
  15814. %@3@%%@CR:C6A00130017 @%%@AB@%13.2.1  Sign Extension%@AE@%%@EH@%%@NL@%
  15815. %@NL@%
  15816. "Sign extension" is the propagation of the sign bit to fill unoccupied space
  15817. when promoting to a more-significant type or when performing bitwise
  15818. right-shift operations.  %@NL@%
  15819. %@NL@%
  15820. %@NL@%
  15821. %@4@%%@AB@%Promotion from Shorter Types%@AE@%%@EH@%%@NL@%
  15822. %@NL@%
  15823. Integral promotions from shorter types occur when you make an assignment,
  15824. perform arithmetic, perform a comparison, or perform an explicit cast.  %@NL@%
  15825. %@NL@%
  15826. The behavior of integral promotion is well defined, except for type %@AB@%char%@AE@%.
  15827. The implementation defines whether type %@AB@%char%@AE@% is treated as signed or
  15828. unsigned. The code fragment below is an example of promotion as a result of
  15829. assignment:  %@NL@%
  15830. %@NL@%
  15831. %@AS@%  char c1 = -3;
  15832. %@AS@%  int  i1;
  15833. %@AS@%  
  15834. %@AS@%  i1 = c1;%@AE@%%@NL@%
  15835. %@NL@%
  15836. In this example, the expected result of the assignment statement is that %@AS@% i1
  15837. %@AS@%%@AE@% will be set to -3. If the implementation defines type %@AB@%char%@AE@% as unsigned,
  15838. however, sign extension will not occur, and %@AS@% i1 %@AE@% will be 253 (on a
  15839. two's-complement machine).  %@NL@%
  15840. %@NL@%
  15841. Promotion can also occur as a result of a comparison of different types:  %@NL@%
  15842. %@NL@%
  15843. %@AS@%  char c;
  15844. %@AS@%  
  15845. %@AS@%  if( c == 0x80 )
  15846. %@AS@%      .
  15847. %@AS@%      .
  15848. %@AS@%      .%@AE@%%@NL@%
  15849. %@NL@%
  15850. This comparison will never evaluate as true on an implementation that
  15851. signextends %@AB@%char%@AE@% types but treats hexadecimal constants as unsigned. Use a
  15852. character constant of the form %@AB@%'\x80'%@AE@%, or explicitly cast the constant to
  15853. type %@AB@%char%@AE@% to perform the comparison correctly.  %@NL@%
  15854. %@NL@%
  15855. The following comparison, which is an example of promotion as a result of a
  15856. cast, is also nonportable:  %@NL@%
  15857. %@NL@%
  15858. %@AS@%  char c;
  15859. %@AS@%  unsigned int u;
  15860. %@AS@%  
  15861. %@AS@%  if( u == (unsigned)c )%@AE@%%@NL@%
  15862. %@NL@%
  15863. There are two problems with this code:  %@NL@%
  15864. %@NL@%
  15865. %@NL@%
  15866.   ■   The %@AB@%char%@AE@% type may be treated as signed or unsigned, depending on the
  15867.       implementation.%@NL@%
  15868. %@NL@%
  15869.   ■   If the %@AB@%char%@AE@% type is treated as signed, it can be converted to %@AB@%unsigned%@AE@%
  15870.       in two different ways: the %@AB@%char%@AE@% value may first be sign-extended to
  15871.       %@AB@%int%@AE@%, then converted to %@AB@%unsigned%@AE@%; or the %@AB@%char%@AE@% may be converted to
  15872.       %@AB@%unsigned char%@AE@%, then sign-extended to %@AB@%int%@AE@% length.%@NL@%
  15873. %@NL@%
  15874. %@NL@%
  15875. It is always safe to compare a %@AB@%signed int%@AE@% with a %@AB@%char%@AE@% constant because C
  15876. requires all character constants to be positive.  %@NL@%
  15877. %@NL@%
  15878. Variables of type %@AB@%char%@AE@% are promoted to type %@AB@%int%@AE@% when passed as arguments to
  15879. a function. This will cause sign extension on some machines. Consider the
  15880. following code:  %@NL@%
  15881. %@NL@%
  15882. %@AS@%  char c = 128;
  15883. %@AS@%  
  15884. %@AS@%  printf( "%d\n", c );%@AE@%%@NL@%
  15885. %@NL@%
  15886. %@NL@%
  15887. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15888. %@NL@%
  15889. Microsoft C allows you to treat type %@AB@%char%@AE@% as signed or unsigned. By default,
  15890. a %@AB@%char%@AE@% is considered signed, but if you change the default %@AB@%char%@AE@% type using
  15891. the /J compiler option, you can treat it as unsigned.  %@NL@%
  15892. %@NL@%
  15893. %@NL@%
  15894. %@4@%%@AB@%Bitwise Right-Shift Operations%@AE@%%@EH@%%@NL@%
  15895. %@NL@%
  15896. Positive or unsigned integral types (%@AB@%char%@AE@%, %@AB@%short%@AE@%, %@AB@%int%@AE@%, and %@AB@%long%@AE@%) yield
  15897. positive or zero values after a right bitwise shift (>>) operation. For
  15898. example,  %@NL@%
  15899. %@NL@%
  15900. %@AS@%  (char)120 >> 4%@AE@%%@NL@%
  15901. %@NL@%
  15902. yields 7,  %@NL@%
  15903. %@NL@%
  15904. %@AS@%  (unsigned char)240 >> 8%@AE@%%@NL@%
  15905. %@NL@%
  15906. yields 0,  %@NL@%
  15907. %@NL@%
  15908. %@AS@%  (int)500 >> 8%@AE@%%@NL@%
  15909. %@NL@%
  15910. yields 1, and  %@NL@%
  15911. %@NL@%
  15912. %@AS@%  (unsigned int)65535 >> 4%@AE@%%@NL@%
  15913. %@NL@%
  15914. yields 4,095.  %@NL@%
  15915. %@NL@%
  15916. Negative-signed integral types yield implementation-defined values after a
  15917. bitwise right-shift operation. This means that you must know whether you
  15918. want to do a signed or unsigned shift, then code accordingly.  %@NL@%
  15919. %@NL@%
  15920. If you don't know how the implementation performs, you may get unexpected
  15921. results. For example, %@AS@% (signed char)0x80 >> 3 %@AE@% yields 0xf0 if the
  15922. imple-mentation performs sign extension on right bitwise shifts. If the
  15923. implementation does not perform the sign extension, the result is 0x10.  %@NL@%
  15924. %@NL@%
  15925. You can use right shifts to speed up division when the divisor can be
  15926. represented by powers of 2 and the dividend is positive. To maintain
  15927. portability, you should use the division operator.  %@NL@%
  15928. %@NL@%
  15929. To perform an unsigned shift, explicitly cast the data to an unsigned type.
  15930. To perform a shift that extends the sign bit, use the division operator as
  15931. follows: divide by 2n, where %@AI@%n%@AE@% is the number of bits you want to shift.  %@NL@%
  15932. %@NL@%
  15933. %@NL@%
  15934. %@3@%%@CR:C6A00130018 @%%@AB@%13.2.2  Length and Case of Identifiers%@AE@%%@EH@%%@NL@%
  15935. %@NL@%
  15936. Some implementations do not support long identifiers. Some allow only 6
  15937. characters, while others allow as many as 32. They may report each
  15938. identifier that exceeds the maximum length or truncate identifiers to a
  15939. given length. Truncation causes serious problems, especially if you have a
  15940. number of similarly named variables within the scope of a block of code,
  15941. such as the following:  %@NL@%
  15942. %@NL@%
  15943. %@AS@%  double acct_receivable_30_days;
  15944. %@AS@%  double acct_receivable_60_days;
  15945. %@AS@%  double acct_receivable_90_days;
  15946. %@AS@%  double current_interest_rate;
  15947. %@AS@%  
  15948. %@AS@%  acct_receivable_30_days *= current_interest_rate;%@AE@%%@NL@%
  15949. %@NL@%
  15950. If your target system retains only six significant characters, you will have
  15951. to rename all your %@AS@% acct_receivable %@AE@% variables.  %@NL@%
  15952. %@NL@%
  15953. Case sensitivity also affects portability. C is usually a case-sensitive
  15954. language. That is, %@AS@% CalculateInterest %@AE@% is not considered the same identifier
  15955. as %@AS@%calculateinterest%@AE@%. Some systems are not case sensitive, however, so to
  15956. write portable code, differentiate your identifiers by something other than
  15957. case.  %@NL@%
  15958. %@NL@%
  15959. These problems with identifiers can occur in two locations: the compiler and
  15960. the linker or loader. Even if the compiler can handle long and
  15961. case-differentiated identifiers, if the linker or loader cannot, you can get
  15962. duplicate definitions or other unexpected errors.  %@NL@%
  15963. %@NL@%
  15964. %@NL@%
  15965. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15966. %@NL@%
  15967. The Microsoft C compiler issues the /NOIGNORECASE command to the Microsoft
  15968. Segmented-Executable Linker (LINK), specifically instructing it to consider
  15969. the case of identifiers.  %@NL@%
  15970. %@NL@%
  15971. %@NL@%
  15972. %@3@%%@CR:C6A00130019 @%%@AB@%13.2.3  Register Variables%@AE@%%@EH@%%@NL@%
  15973. %@NL@%
  15974. The number and type of register variables in a function depend on the
  15975. implementation. You can declare more variables as %@AB@%register %@AE@%than the number
  15976. of physical registers the implementation uses. In such a case, the compiler
  15977. treats the excess register variables as %@AB@%automatic%@AE@%.  %@NL@%
  15978. %@NL@%
  15979. Since the types that qualify for %@AB@%register%@AE@% class differ among
  15980. implementations, invalid %@AB@%register %@AE@%declarations are treated as %@AB@%automatic%@AE@%.  %@NL@%
  15981. %@NL@%
  15982. If you declare variables as %@AB@%register %@AE@%to optimize performance, declare them
  15983. in decreasing order of importance to ensure that the compiler allocates a
  15984. register to the most important variables.  %@NL@%
  15985. %@NL@%
  15986. %@NL@%
  15987. %@4@%%@AB@%Microsoft C Specific%@AE@%%@EH@%%@NL@%
  15988. %@NL@%
  15989. The compiler ignores %@AB@%register%@AE@% declarations if you select the global register
  15990. allocation optimization. You can select global register allocation as
  15991. follows:  %@NL@%
  15992. %@NL@%
  15993. %@AB@%Environment%@AE@%                       %@AB@%Selection%@AE@%
  15994. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15995. CL command line                   Specify either the /Oe or /Ox option.
  15996.  
  15997. PWB                               Select the Global Register Allocation 
  15998.                                   option in the Debug Build Options or 
  15999.                                   Release Build Options dialog boxes.
  16000.  
  16001. pragma                            Use the %@AB@%optimize%@AE@% pragma with the %@AB@%e%@AE@% 
  16002.                                   parameter.
  16003.  
  16004. %@NL@%
  16005. %@3@%%@CR:C6A00130020 @%%@AB@%13.2.4  Functions with a Variable Number of Arguments%@AE@%%@EH@%%@NL@%
  16006. %@NL@%
  16007. Functions that accept a variable number of arguments are not portable.
  16008. Although both the ANSI Standard and %@AI@%The C Programming Language%@AE@% specify how
  16009. to write these functions and how they behave, differences still exist among
  16010. compiler implementors about how to use variable argument lists.  %@NL@%
  16011. %@NL@%
  16012. Many UNIX(R) systems support a standard that differs from the ANSI Standard
  16013. for variable arguments. Although this may change, it currently presents a
  16014. portability concern.  %@NL@%
  16015. %@NL@%
  16016. Microsoft C run-time libraries and macros allow you to use whichever version
  16017. of variable argument support you expect to be most portable for your
  16018. application.  %@NL@%
  16019. %@NL@%
  16020. %@NL@%
  16021. %@3@%%@CR:C6A00130021 @%%@AB@%13.2.5  Evaluation Order%@AE@%%@EH@%%@NL@%
  16022. %@NL@%
  16023. The C language does not guarantee the evaluation order of most expressions.
  16024. Avoid writing constructs that depend on evaluation within an expression to
  16025. proceed in a particular manner. For example,  %@NL@%
  16026. %@NL@%
  16027. %@AS@%  i = 0;
  16028. %@AS@%  func( i++, i++ );
  16029. %@AS@%  .
  16030. %@AS@%  .
  16031. %@AS@%  .
  16032. %@AS@%  func( int a, int b )
  16033. %@AS@%  {%@AE@%%@NL@%
  16034. %@NL@%
  16035. A compiler could evaluate this code fragment and pass 0 as %@AS@% a %@AE@% and 1 as %@AS@% b%@AE@%.
  16036. It could also pass 1 as %@AS@% a %@AE@% and 0 as %@AS@% b %@AE@% and conform equally with the
  16037. standards.  %@NL@%
  16038. %@NL@%
  16039. The C language does guarantee that an expression will be completely
  16040. evaluated at any given "sequence point." A sequence point is a point in the
  16041. syntax of the language at which all side effects of an expression or series
  16042. of expressions have been completed.  %@NL@%
  16043. %@NL@%
  16044. These are the sequence points in the C language:  %@NL@%
  16045. %@NL@%
  16046. %@NL@%
  16047.   1.  The semicolon (;) statement separator%@NL@%
  16048. %@NL@%
  16049.   2.  The call to a function after the arguments have been evaluated%@NL@%
  16050. %@NL@%
  16051.   3.  The end of the first operand of one of the following:
  16052. %@NL@%
  16053.       ■   Logical AND (%@AB@%&&%@AE@%)%@NL@%
  16054. %@NL@%
  16055.       ■   Logical OR (%@AB@%||%@AE@%)%@NL@%
  16056. %@NL@%
  16057.       ■   Conditional (%@AB@%?%@AE@%)%@NL@%
  16058. %@NL@%
  16059.       ■   Comma separator (%@AB@%,%@AE@%) when used to separate statements or in
  16060.           expressions; the comma separator is not a sequence point when it
  16061.           is used between variables in declaration statements or between
  16062.           parameters in a function  invocation%@NL@%
  16063. %@NL@%
  16064. %@NL@%
  16065.   4.  The end of a full expression, such as
  16066. %@NL@%
  16067.       ■   An initializer%@NL@%
  16068. %@NL@%
  16069.       ■   The expression in an expression statement (for example, any
  16070.           expression inside parentheses)%@NL@%
  16071. %@NL@%
  16072.       ■   The controlling expression of a %@AB@%while %@AE@%or %@AB@%do %@AE@%statement%@NL@%
  16073. %@NL@%
  16074.       ■   Any of the three expressions of a %@AB@%for %@AE@%statement%@NL@%
  16075. %@NL@%
  16076.       ■   The expression in a %@AB@%return %@AE@%statement%@NL@%
  16077. %@NL@%
  16078. %@NL@%
  16079. %@NL@%
  16080. %@NL@%
  16081. %@3@%%@CR:C6A00130022 @%%@AB@%13.2.6  Function and Macro Arguments with Side Effects%@AE@%%@EH@%%@NL@%
  16082. %@NL@%
  16083. Run-time support functions can be implemented either as functions or as
  16084. macros. Avoid including expressions with side effects inside function
  16085. invocations unless you are sure the function will not be implemented as a
  16086. macro. Here is an illustration of how an argument with side effects can
  16087. cause problems:  %@NL@%
  16088. %@NL@%
  16089. %@AS@%  #define limit_number(a) ((a>1000)?1000:(a))
  16090. %@AS@%  
  16091. %@AS@%  a = limit_number( a++ );%@AE@%%@NL@%
  16092. %@NL@%
  16093. If %@AS@% a ≤%@AE@% 1000, it is incremented once. If %@AS@% a %@AE@%> 1000, it is incremented twice,
  16094. which is probably not the intended behavior.  %@NL@%
  16095. %@NL@%
  16096. A macro can be used safely with an argument that has side effects if it
  16097. evaluates its parameter only once. You can determine whether a macro is safe
  16098. only by inspecting the code.  %@NL@%
  16099. %@NL@%
  16100. A common example of a run-time support function that is often implemented as
  16101. a macro is %@AB@%toupper%@AE@%. You will find your program's behavior confusing if you
  16102. use the following code:  %@NL@%
  16103. %@NL@%
  16104. %@AS@%  char c;
  16105. %@AS@%  
  16106. %@AS@%  c = toupper( getc() );%@AE@%%@NL@%
  16107. %@NL@%
  16108. If %@AS@% toupper %@AE@% is implemented as a function, %@AS@% getc %@AE@% will be called only once,
  16109. and its return value will be translated to uppercase. However, if %@AS@% toupper %@AE@%
  16110. is implemented as a macro, %@AS@% getc %@AE@% will be called once or twice, depending on
  16111. whether %@AS@% c %@AE@%is upper- or lowercase. Consider the following macro example:  %@NL@%
  16112. %@NL@%
  16113. %@AS@%  #define toupper(c) ( (islower(c)) ? _toupper(c) : (c) )%@AE@%%@NL@%
  16114. %@NL@%
  16115. If you include the %@AB@%toupper%@AE@% macro in your code, the preprocessor expands it
  16116. as follows:  %@NL@%
  16117. %@NL@%
  16118. %@AS@%  /* What you wrote */
  16119. %@AS@%  c = toupper( getc() );
  16120. %@AS@%  
  16121. %@AS@%  /* Macro expansion */
  16122. %@AS@%  ch = (islower( (getc()) ) ? _toupper( getc() ) : (getc()) );%@AE@%%@NL@%
  16123. %@NL@%
  16124. The expansion of the macro shows that the argument to %@AS@% toupper %@AE@% will always
  16125. be called twice: once to determine if the character is lowercase and the
  16126. next time to perform case translation (if necessary). In the example, this
  16127. double evaluation calls the %@AB@%getc%@AE@% function twice. Because %@AS@% getc %@AE@% is a
  16128. function whose side effect is to read a character from the standard input
  16129. device, the example requests two characters from standard input.  %@NL@%
  16130. %@NL@%
  16131. %@NL@%
  16132. %@3@%%@CR:C6A00130023 @%%@AB@%13.2.7  Environment Differences%@AE@%%@EH@%%@NL@%
  16133. %@NL@%
  16134. Many programs perform some file I/O. When writing these programs for
  16135. portability, consider the following:  %@NL@%
  16136. %@NL@%
  16137. %@NL@%
  16138.   ■   Do not hard-code file or path names. Use constants you define either
  16139.       in a header file or at the beginning of the program.%@NL@%
  16140. %@NL@%
  16141.   ■   Do not assume the use of any particular file system. For example, the
  16142.       UNIX-model, hierarchical file system is prevalent on small computers.
  16143.       On larger systems, the file system often follows a different model.%@NL@%
  16144. %@NL@%
  16145.   ■   Do not assume a particular display size (number of rows and columns).%@NL@%
  16146. %@NL@%
  16147.   ■   Do not assume that display attributes exist. Some environments do not
  16148.       support such attributes as color, underlined text, blinking text,
  16149.       highlighted text, inverse text, protected text, or dim text.%@NL@%
  16150. %@NL@%
  16151. %@NL@%
  16152. %@NL@%
  16153. %@2@%%@CR:C6A00130024 @%%@AB@%13.3  Portability of Data Files%@AE@%%@EH@%%@NL@%
  16154. %@NL@%
  16155. Data files are rarely portable across different CPUs. Structures, unions,
  16156. and arrays have varying internal layout and alignment requirements on
  16157. different machines. In addition, byte ordering within words and actual word
  16158. length may vary.  %@NL@%
  16159. %@NL@%
  16160. The best way to achieve data-file portability is to write and read data
  16161. files as one-dimensional character arrays. This procedure prevents alignment
  16162. and padding problems if the data are written and read as characters. The
  16163. only portability problem you are likely to encounter if you follow this
  16164. course is a conflict in character sets; many computers have character-set
  16165. conversion utilities.  %@NL@%
  16166. %@NL@%
  16167. %@NL@%
  16168. %@2@%%@CR:C6A00130025 @%%@AB@%13.4  Portability Concerns Specific to Microsoft C%@AE@%%@EH@%%@NL@%
  16169. %@NL@%
  16170. Microsoft C offers extensions that let you take advantage of the full
  16171. capabilities of the computer. These extensions are not portable to other
  16172. compilers or environments. The following list shows keywords specific to
  16173. Microsoft C:  %@NL@%
  16174. %@NL@%
  16175. %@AB@%_asm               _far            _huge           pascal%@AE@%
  16176. %@AB@%_based          _fastcall       _interrupt      _pascal%@AE@%
  16177. %@AB@%cdecl           fortran         near            _saveregs%@AE@%
  16178. %@AB@%_cdecl          _fortran        _near           _segment%@AE@%
  16179. %@AB@%_export         huge            _loadds         _segname%@AE@%
  16180. %@AB@%far             
  16181.  
  16182. The %@AI@%Microsoft C Reference%@AE@% contains compatibility information for every
  16183. function in the run-time library. Any function or macro that does not have
  16184. the ANSI box marked may not be portable to other compilers or computer
  16185. systems.  %@NL@%
  16186. %@NL@%
  16187. %@NL@%
  16188. %@2@%%@CR:C6A00130026 @%%@AB@%13.5  Microsoft C Byte Ordering%@AE@%%@EH@%%@NL@%
  16189. %@NL@%
  16190. Tables 13.4 and 13.5 summarize Microsoft C byte ordering for %@AB@%short%@AE@% and %@AB@%long%@AE@%
  16191. types, respectively. In these tables, the least-significant byte of the data
  16192. item is b0; the next byte is denoted by b1, and so on.  %@NL@%
  16193. %@NL@%
  16194. Since byte ordering is machine specific, any program that uses this byte
  16195. ordering will not be portable.  %@NL@%
  16196. %@NL@%
  16197. %@AB@%Table 13.4  %@AB@%Byte Ordering for Short Types%@AE@%%@AE@%
  16198.  
  16199. %@TH:   9   473 02 28 48 @%
  16200. CPU                         Byte Order
  16201. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16202. 8086                        b0   b1
  16203. 80286                       b0   b1
  16204. PDP-11(R)                   b0   b1
  16205. VAX-11(R)                   b0   b1
  16206. M68000                      b1   b0
  16207. Z8000(R)                    b1   b0
  16208. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16209. %@TE:   9   473 02 28 48 @%
  16210.  
  16211. %@AB@%Table 13.5  %@AB@%Byte Ordering for Long Types%@AE@%%@AE@%
  16212.  
  16213. %@TH:   9   494 02 25 51 @%
  16214. CPU                      Byte Order
  16215. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16216. 8086                     b0  b1  b2  b3
  16217. 80286                    b0  b1  b2  b3
  16218. PDP-11                   b2  b3  b0  b1
  16219. VAX-11                   b0  b1  b2  b3
  16220. M68000                   b3  b2  b1  b0
  16221. Z8000                    b3  b2  b1  b0
  16222. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16223. %@TE:   9   494 02 25 51 @%
  16224.  
  16225. %@NL@%
  16226. %@NL@%
  16227. %@NL@%
  16228. %@NL@%
  16229. %@NL@%
  16230. %@CR:C6A-Part 04 @%%@1@%%@AB@%PART IV  OS/2 Support%@AE@%%@EH@%%@NL@%
  16231. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16232. %@NL@%
  16233. The Microsoft C Professional Development System provides support for OS/2
  16234. development.  %@NL@%
  16235. %@NL@%
  16236. Chapter 14 explains many of the general issues of OS/2 development,
  16237. including accessing the OS/2 system functions, creating module-definition
  16238. files, and using the OS/2-specific features of utilities such as the linker
  16239. and BIND. Chapter 15 focuses on how to create a multithread application,
  16240. including information about C run-time library support, potential problem
  16241. areas, and how to use CodeView to debug multithread applications. Chapter 16
  16242. concentrates on the creation of dynamic-link libraries, including C run-time
  16243. library support, application program interface with DLLs, and debugging DLLs
  16244. with CodeView.  %@NL@%
  16245. %@NL@%
  16246. %@NL@%
  16247. %@NL@%
  16248. %@NL@%
  16249. %@NL@%
  16250. %@NL@%
  16251. %@CR:C6A00140001 @%%@1@%%@AB@%Chapter 14  Building OS/2 Applications%@AE@%%@EH@%%@NL@%
  16252. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16253. %@NL@%
  16254. Using Microsoft C 6.0, you can create applications for OS/2. This chapter
  16255. explains features in the compiler and the utilities that  %@NL@%
  16256. %@NL@%
  16257. %@NL@%
  16258.   ■   Call the OS/2 operating system directly from C functions%@NL@%
  16259. %@NL@%
  16260.   ■   Perform multitasking within your program by starting multiple
  16261.       execution paths known as "threads"%@NL@%
  16262. %@NL@%
  16263.   ■   Create dynamic-link libraries that can be used by multiple
  16264.       applications%@NL@%
  16265. %@NL@%
  16266.   ■   Work in either OS/2 or DOS to create programs for both environments%@NL@%
  16267. %@NL@%
  16268.   ■   Develop "dual-mode" applications that will run under both OS/2 and DOS
  16269.       from a single executable program file%@NL@%
  16270. %@NL@%
  16271. %@NL@%
  16272. This chapter contains information about accessing the OS/2 Applications
  16273. Program Interface (API) from your C programs. It also discusses compile
  16274. options that affect applications you develop for OS/2, module-definition
  16275. files and import libraries, linker options specific to developing OS/2
  16276. applications, and using the BIND utility to create dual-mode applications.  %@NL@%
  16277. %@NL@%
  16278. Chapters 15 and 16, "Creating Multithread OS/2 Applications" and
  16279. "Dynamic-Linking with OS/2," contain detailed information about how
  16280. Microsoft C supports these advanced OS/2 features.  %@NL@%
  16281. %@NL@%
  16282. %@NL@%
  16283. %@2@%%@CR:C6A00140002 @%%@AB@%14.1  The OS/2 Applications Program Interface%@AE@%%@EH@%%@NL@%
  16284. %@NL@%
  16285. The entire set of OS/2 system calls is known as the OS/2 API. You need to
  16286. access the OS/2 API for the low-level functions provided by the operating
  16287. system, such as  %@NL@%
  16288. %@NL@%
  16289. %@NL@%
  16290.   ■   Requests for information about the display%@NL@%
  16291. %@NL@%
  16292.   ■   Requests to display information%@NL@%
  16293. %@NL@%
  16294.   ■   Requests for information from the pointing device (mouse)%@NL@%
  16295. %@NL@%
  16296.   ■   Requests for information from the keyboard%@NL@%
  16297. %@NL@%
  16298.   ■   Requests for blocks of memory%@NL@%
  16299. %@NL@%
  16300.   ■   Requests for disk actions, including reading and writing%@NL@%
  16301. %@NL@%
  16302. %@NL@%
  16303. You can call all of the OS/2 system services directly from programs written
  16304. in C. Under DOS, the API operates at a lower level, requiring programs to
  16305. set up hardware registers and generate a software interrupt to access the
  16306. system services. Under OS/2, programs use function calls to access the
  16307. operating system services.  %@NL@%
  16308. %@NL@%
  16309. Sections 14.1.1-14.1.3 describe the calling conventions and precautions you
  16310. must observe when accessing OS/2 API functions.  %@NL@%
  16311. %@NL@%
  16312. %@NL@%
  16313. %@3@%%@CR:C6A00140003 @%%@AB@%14.1.1  Calling the OS/2 API%@AE@%%@EH@%%@NL@%
  16314. %@NL@%
  16315. Your program must declare calls to the OS/2 API with both the %@AB@%_far%@AE@% and
  16316. %@AB@%_pascal%@AE@% keywords. Adding the %@AB@%_pascal%@AE@% keyword to the function declaration
  16317. ensures that the FORTRAN/Pascal calling convention is used. The %@AB@%_far%@AE@% keyword
  16318. directs the compiler to generate an intersegment call instruction. A sample
  16319. declaration for the OS/2 API function %@AB@%DosExit%@AE@% follows:%@CR:C6A00140004 @%  %@NL@%
  16320. %@NL@%
  16321. %@AS@%  void _far _pascal DosExit( unsigned int, unsigned int );%@AE@%%@NL@%
  16322. %@NL@%
  16323. You must be sure that all pointers passed to OS/2 API functions are far
  16324. pointers, even if you are writing a program using the small or medium memory
  16325. models. This process can be simplified if you include the OS2.H header file.
  16326. %@NL@%
  16327. %@NL@%
  16328. %@AU@% OS/2 API function calls are far and must use the FORTRAN/ Pascal calling
  16329. %@AU@%convention.%@AE@%  %@NL@%
  16330. %@NL@%
  16331. OS/2 API functions use the FORTRAN/Pascal language calling convention. They
  16332. expect arguments to be pushed onto the stack in left-to-right order, with
  16333. the last argument in the list pushed onto the stack last. OS/2 API functions
  16334. remove their arguments from the stack before returning to the caller.
  16335. Standard C functions push their arguments from right to left, with the first
  16336. argument being the last one pushed.  %@NL@%
  16337. %@NL@%
  16338. All OS/2 API functions return 0 if the operation is successful. They return
  16339. an error code if the operation fails.  %@NL@%
  16340. %@NL@%
  16341. %@NL@%
  16342. %@3@%%@CR:C6A00140005 @%%@AB@%14.1.2  Including the OS/2 Header Files%@AE@%%@EH@%%@NL@%
  16343. %@NL@%
  16344. You do not have to construct your own API declarations if you use the OS2.H
  16345. header file. It is the first file of a set of header files that supply
  16346. function prototypes for every OS/2 API call and definitions of special OS/2
  16347. structures, data types, and constants.  %@NL@%
  16348. %@NL@%
  16349. The API function prototypes define all functions as far procedures with the
  16350. FORTRAN/Pascal calling convention. They also take care of casting all near
  16351. pointers to far pointers and other similar type coercions.  %@NL@%
  16352. %@NL@%
  16353. %@AU@% Define a constant before including OS2.H.%@AE@%  %@NL@%
  16354. %@NL@%
  16355. When you include OS2.H, the most commonly used data types and macros are
  16356. automatically defined. To minimize compile time for the C preprocessor,
  16357. other definitions are grouped by function. They are included only if your
  16358. source file defines the appropriate constant before including OS2.H. The
  16359. following list shows how these manifest constants affect functions from the
  16360. OS/2 API:  %@NL@%
  16361. %@NL@%
  16362. %@AB@%Constant%@AE@%                          %@AB@%Effect%@AE@%
  16363. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16364. %@AB@%INCL_BASE%@AE@%                         All error constants, kernel, keyboard, 
  16365.                                   video, and mouse definitions (same as %@AB@%%@AE@%
  16366.                                   %@AB@%INCL_DOS%@AE@% +%@AB@% INCL_SUB%@AE@% + %@AB@%INCL_DOSERRORS%@AE@%)
  16367.  
  16368. %@AB@%INCL_DOS%@AE@%                          All kernel system definitions
  16369.  
  16370. %@AB@%INCL_DOSERRORS%@AE@%                    All error constants
  16371.  
  16372. %@AB@%INCL_KBD%@AE@%                          All keyboard definitions
  16373.  
  16374. %@AB@%INCL_MOU%@AE@%                          All mouse definitions
  16375.  
  16376. %@AB@%INCL_SUB%@AE@%                          All keyboard, video, and mouse 
  16377.                                   definitions (same as %@AB@%INCL_KBD%@AE@% + %@AB@%INCL_VIO%@AE@%
  16378.                                   + %@AB@%INCL_MOU)%@AE@%
  16379.  
  16380. %@AB@%INCL_VIO%@AE@%                          All video-display definitions
  16381.  
  16382. %@AB@%INCL_WIN%@AE@%                          Basic set of Presentation Manager 
  16383.                                   definitions
  16384.  
  16385. The header files have additional constants that let you include smaller
  16386. subsets or functions not defined in the standard sets.  %@NL@%
  16387. %@NL@%
  16388. %@AU@% The statement #define INCL_DOS affects the functions defined.%@AE@%  %@NL@%
  16389. %@NL@%
  16390. The program in the example below calls the OS/2 kernel to request a
  16391. nonshareable, nondiscardable memory segment for an 8K buffer. The %@AB@%INCL_DOS%@AE@%
  16392. constant in the %@AB@%#define%@AE@% statement instructs the C preprocessor to include
  16393. all of the kernel function definitions. The function prototype for
  16394. %@AB@%DosAllocSeg%@AE@% declares the first and third arguments as %@AB@%USHORT%@AE@% (unsigned short
  16395. integers). The second argument is a far pointer to the OS/2 data type %@AB@%SEL%@AE@%,
  16396. which is used for segment selectors.  %@NL@%
  16397. %@NL@%
  16398. %@AS@%  #define  INCL_DOS
  16399. %@AS@%  #include <os2.h>
  16400. %@AS@%  
  16401. %@AS@%  VOID GetMemorySegment()
  16402. %@AS@%  {
  16403. %@AS@%       SEL    selector;
  16404. %@AS@%  
  16405. %@AS@%       if ( DosAllocSeg( 8192, &selector, 0 ) )
  16406. %@AS@%           puts( "Allocation failed\n" );
  16407. %@AS@%       else
  16408. %@AS@%           puts( "Successful allocation\n" );
  16409. %@AS@%  }%@AE@%%@NL@%
  16410. %@NL@%
  16411. The function call in the example works correctly even in a small or medium
  16412. memory model program where the selector variable is a %@AB@%near data%@AE@% type. All
  16413. three arguments are coerced by the function prototype to the proper types,
  16414. regardless of the memory model used.  %@NL@%
  16415. %@NL@%
  16416. %@NL@%
  16417. %@3@%%@CR:C6A00140006 @%%@AB@%14.1.3  Creating Dual-Mode Programs as Family Applications%@AE@%%@EH@%%@NL@%
  16418. %@NL@%
  16419. The OS/2 API has a subset of system functions that have direct DOS
  16420. equivalents. This subset is known as the "Family Applications Program
  16421. Interface" (Family API). Programs that use only the Family API can be run
  16422. under DOS and the OS/2 compatibility box, as well as under OS/2.  %@NL@%
  16423. %@NL@%
  16424. %@AU@% You can build a single executable file for use under both OS/2 and DOS.%@AE@%  %@NL@%
  16425. %@NL@%
  16426. By creating a Family API application, you can distribute the same executable
  16427. file to both OS/2 and DOS users. The Microsoft C compiler, linker, and
  16428. object module librarian are examples of family applications. The benefit of
  16429. having a single executable file is offset by a few disadvantages:  %@NL@%
  16430. %@NL@%
  16431. %@NL@%
  16432.   ■   The executable file is larger, because it includes a special loader
  16433.       and OS/2 API-simulator routines for running in DOS mode.%@NL@%
  16434. %@NL@%
  16435.   ■   In real mode, the application loads more slowly than a program created
  16436.       specifically for either OS/2 or DOS. There is no performance penalty
  16437.       in loading or running in OS/2 protected mode.%@NL@%
  16438. %@NL@%
  16439.   ■   When running in real mode, the program cannot use advanced OS/2
  16440.       features such as multiple threads or system calls that are not part of
  16441.       the Family API. If you take special precautions (described in Section
  16442.       14.5, "The BIND Utility"), the program can take advantage of these
  16443.       features when running in OS/2 protected mode. %@NL@%
  16444. %@NL@%
  16445. %@NL@%
  16446. Follow the same steps to build both family and protected-mode applications
  16447. but add an extra step at the end to create the Family API program. This step
  16448. links functions from the dynamic-link libraries directly into a stand-alone
  16449. executable file that can run in both real and protected mode.  %@NL@%
  16450. %@NL@%
  16451. %@NL@%
  16452. %@4@%%@AB@%Restrictions on Family Applications%@AE@%%@EH@%%@NL@%
  16453. %@NL@%
  16454. Programs that use the Family API are subject to certain restrictions:  %@NL@%
  16455. %@NL@%
  16456. %@NL@%
  16457.   ■   They cannot overcommit memory; they must fit into the DOS 640K
  16458.       environment.%@NL@%
  16459. %@NL@%
  16460.   ■   They cannot use advanced OS/2 features, such as threads and
  16461.       semaphores, that do not have DOS counterparts.%@NL@%
  16462. %@NL@%
  16463.   ■   They must restrict their use of some calls to the defined common
  16464.       subset. For example, some of the file-mode options for the %@AB@%DosOpen%@AE@%
  16465.       function are not available in real mode.%@NL@%
  16466. %@NL@%
  16467. %@NL@%
  16468. %@NL@%
  16469. %@4@%%@AB@%Family API Functions%@AE@%%@EH@%%@NL@%
  16470. %@NL@%
  16471. The system calls that make up Family API are listed below. The calls marked
  16472. with an asterisk (*) have different options or behavior, depending on
  16473. whether they are running in real mode or protected mode. The %@AI@%Microsoft OS/2
  16474. %@AI@%Programmer's Reference%@AE@% explains the functions and the differences between
  16475. their real- and protected-mode implementations.  %@NL@%
  16476. %@NL@%
  16477. %@AB@%DosAllocHuge*        DosHoldSignal*       DosSubSet%@AE@%
  16478. %@AB@%DosAllocSeg*         DosInsMessage*       DosWrite%@AE@%
  16479. %@AB@%DosBeep              DosMkDir             KbdCharIn*%@AE@%
  16480. %@AB@%DosBufReset          DosMove              KbdFlushBuffer*%@AE@%
  16481. %@AB@%DosCaseMap*          DosNewSize           KbdGetStatus*%@AE@%
  16482. %@AB@%DosChdir             DosOpen*             KbdPeek*%@AE@%
  16483. %@AB@%DosChgFilePtr        DosPutMessage*       KbdSetStatus*%@AE@%
  16484. %@AB@%DosCLIAccess         DosQCurDir           KbdStringIn*%@AE@%
  16485. %@AB@%DosClose             DosQCurDisk          VioGetBuf%@AE@%
  16486. %@AB@%DosCreateCSAlias*    DosQFHandState       VioGetConfig%@AE@%
  16487. %@AB@%DosDelete            DosQFileInfo         VioGetCurPos%@AE@%
  16488. %@AB@%DosDevConfig         DosQFileMode         VioGetCurType%@AE@%
  16489. %@AB@%DosDevIOCtl*         DosQFSInfo           VioGetMode%@AE@%
  16490. %@AB@%DosDupHandle         DosQHandType         VioGetPhysBuf%@AE@%
  16491. %@AB@%DosErrClass          DosQVerify           VioReadCellStr%@AE@%
  16492. %@AB@%DosError*            DosRead*             VioReadCharStr%@AE@%
  16493. %@AB@%DosExecPgm*          DosReallocHuge*      VioScrLock*%@AE@%
  16494. %@AB@%DosExit*             DosReallocSeg*       VioScrollDn%@AE@%
  16495. %@AB@%DosFileLocks         DosRmDir             VioScrollLf%@AE@%
  16496. %@AB@%DosFindClose         DosSelectDisk        VioScrollRt%@AE@%
  16497. %@AB@%DosFindFirst         DosSetCp             VioScrollUp%@AE@%
  16498. %@AB@%DosFindNext*         DosSetDateTime       VioScrUnLock%@AE@%
  16499. %@AB@%DosFreeSeg*          DosSetFHandState*    VioSetCurPos%@AE@%
  16500. %@AB@%DosGetCollate*       DosSetFileInfo       VioSetCurType%@AE@%
  16501. %@AB@%DosGetCp             DosSetFileMode       VioSetMode%@AE@%
  16502. %@AB@%DosGetCtryInfo*      DosSetFSInfo         VioShowBuf%@AE@%
  16503. %@AB@%DosGetDateTime       DosSetSigHandler*    VioWrtCellStr%@AE@%
  16504. %@AB@%DosGetDBSCEv*        DosSetVec*           VioWrtCharStr%@AE@%
  16505. %@AB@%DosGetEnv            DosSetVerify         VioWrtCharStrAtt%@AE@%
  16506. %@AB@%DosGetHugeShift      DosSizeSeg           VioWrtNAttr%@AE@%
  16507. %@AB@%DosGetMachineMode    DosSleep             VioWrtNCell%@AE@%
  16508. %@AB@%DosGetMessage*       DosSubAlloc          VioWrtNChar%@AE@%
  16509. %@AB@%DosGetVersion        DosSubFree           VioWrtTTy %@AE@%
  16510.  
  16511. %@2@%%@CR:C6A00140007 @%%@AB@%14.2  Compile Options for the CL Command%@AE@%%@EH@%%@NL@%
  16512. %@NL@%
  16513. This section describes the compile options you must specify in the
  16514. Programmer's WorkBench or on the CL command line to designate a program's
  16515. target environment (OS/2, DOS, or both). It also introduces options you
  16516. should use with certain types of OS/2 applications, such as multithread
  16517. programs, dynamic-link libraries, and programs calling C function
  16518. dynamic-link libraries. For an in-depth discussion of topics that affect
  16519. multithread processes and dynamic-link libraries, see Chapter 15, "Creating
  16520. Multithread OS/2 Applications," and Chapter 16, "Dynamic-Linking with OS/2."
  16521. %@NL@%
  16522. %@NL@%
  16523. %@NL@%
  16524. %@3@%%@CR:C6A00140008 @%%@AB@%14.2.1  The Link Mode Options (/Lp, /Lr, and /Lc)%@AE@%%@EH@%%@NL@%
  16525. %@NL@%
  16526. The /L%@AI@%x%@AE@% options (/Lp, /Lr, and /Lc) provide the flexibility of programming
  16527. for both OS/2 and DOS in either environment. Regardless of the host
  16528. operating system, you can build applications for either target operating
  16529. system. You do not have to switch to the target system to build the program.
  16530. %@NL@%
  16531. %@NL@%
  16532. The /Lp option produces an OS/2 protected-mode program; the /Lr option
  16533. creates a DOS real-mode program. /Lc is a synonym for /Lr.%@CR:C6A00140009 @%%@CR:C6A00140010 @%%@CR:C6A00140011 @%%@CR:C6A00140012 @%  %@NL@%
  16534. %@NL@%
  16535. To use these options, the mode-specific combined libraries must be
  16536. installed. Unless you choose a default operating environment, each
  16537. mode-specific library has the letter P or R at the end of its base name. For
  16538. example, the protected-mode small memory model library with the emulator
  16539. floating-point option is named SLIBCEP.LIB. The corresponding real-mode
  16540. library is named SLIBCER.LIB. The default name, however, is SLIBCE.LIB.  %@NL@%
  16541. %@NL@%
  16542. %@AI@%Installing and Using the Microsoft C Professional Development System%@AE@%
  16543. describes how to create mode-specific libraries with the SETUP program. It
  16544. also explains how to establish a default target environment by renaming
  16545. libraries. A default environment is useful if you work mainly in one mode
  16546. (OS/2 or DOS) but sometimes write programs for the other mode. When you set
  16547. up OS/2 as the default mode, SLIBCEP.LIB, for example, becomes SLIBCE.LIB.  %@NL@%
  16548. %@NL@%
  16549. %@AU@% Don't use /Lx options unless you have mode-specific libraries.%@AE@%  %@NL@%
  16550. %@NL@%
  16551. When you use the /L%@AI@%x%@AE@% options, you instruct the compiler to override the
  16552. default library name in the object module's library search record and to
  16553. substitute the mode-specific combined library name. The compiler also
  16554. generates a link response file with the /NODEFAULTLIBRARYSEARCH (/NOD)
  16555. linker option to override the default library. See Section 14.4, "Link
  16556. Command-Line Options," for more information about the /NOD option.  %@NL@%
  16557. %@NL@%
  16558. Do not use the /Lp option to specify protected mode when OS/2 is the default
  16559. environment. If you do this, the compiler uses the name of the mode-specific
  16560. library (e.g., SLIBCEP.LIB). Because SETUP renamed the library to SLIBCE.LIB
  16561. to create a default environment, the library search fails. This caution also
  16562. applies to specifying /Lr when you have installed DOS as the default
  16563. environment.  %@NL@%
  16564. %@NL@%
  16565. If you invoke the linker in a separate step from the compilation, you must
  16566. specify the /NOD link option.  %@NL@%
  16567. %@NL@%
  16568. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16569. NOTE
  16570.  
  16571. %@AI@%There is a special library, LLIBCMT, for building multithread OS/2
  16572. %@AI@%applications. Another special library, LLIBCDLL, supports multithread
  16573. %@AI@%dynamic-link libraries. If you use LLIBCMT or LLIBCDLL, you must use one of
  16574. %@AI@%the library selection options described in Section 14.2.3 instead of %@AI@%/%@AE@%%@AI@% Lp.%@AE@%%@AE@%%@NL@%
  16575. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  16576. %@NL@%
  16577. %@NL@%
  16578. %@3@%%@CR:C6A00140013 @%%@AB@%14.2.2  Creating Bound Programs Option (/Fb)%@AE@%%@EH@%%@NL@%
  16579. %@NL@%
  16580. The /Fb option allows you to compile, link, and bind an application in one
  16581. step. Binding an executable file creates a Family API program that can run
  16582. under both OS/2 and DOS.%@CR:C6A00140014 @%%@CR:C6A00140015 @%%@CR:C6A00140016 @%  %@NL@%
  16583. %@NL@%
  16584. When you use /Fb, the compiler invokes the BIND utility program immediately
  16585. after the link step. You can also execute BIND directly (as described in
  16586. Section 14.5, "The BIND Utility"). You must have the API.LIB and OS2.LIB
  16587. files in the path specified by the LIB environment variable or in your
  16588. current working directory.  %@NL@%
  16589. %@NL@%
  16590. The syntax for the /Fb option is  %@NL@%
  16591. %@NL@%
  16592. %@AS@%  /Fb«bound-exe»%@AE@%%@NL@%
  16593. %@NL@%
  16594. %@AU@% You can specify a separate name for a bound-executable file.%@AE@%  %@NL@%
  16595. %@NL@%
  16596. The optional %@AI@%bound-exe%@AE@% parameter specifies the name of the bound program. It
  16597. must directly follow the /Fb option, without intervening spaces. The
  16598. %@AI@%bound-exe%@AE@% name can be a file specification, a drive name, or a directory
  16599. specification. If you specify a file name without an extension, the compiler
  16600. appends the .EXE extension to the name. If you give a directory
  16601. specification for %@AI@%bound-exe%@AE@%, the name must end with a backslash ( \ ) so the
  16602. compiler can distinguish it from an ordinary file name. If you do not supply
  16603. a name, BIND uses the name of the unbound program and overwrites it.  %@NL@%
  16604. %@NL@%
  16605. When creating both bound and protected-mode versions with different names,
  16606. consider this example:  %@NL@%
  16607. %@NL@%
  16608. %@AS@%  CL /Lp /Fbsampleb sample.c%@AE@%%@NL@%
  16609. %@NL@%
  16610. The protected-mode executable file that this command creates is called
  16611. SAMPLE.EXE; the bound-executable file is called SAMPLEB.EXE.  %@NL@%
  16612. %@NL@%
  16613. %@AU@% You may need to run BIND as a separate step instead of using the /Fb
  16614. %@AU@%option.%@AE@%  %@NL@%
  16615. %@NL@%
  16616. The /Fb option works only if you are doing a single-step compile and link.
  16617. If the CL command line includes the /c (compile without link) option, the
  16618. compiler ignores the /Fb option. If you use /c, you must run the BIND
  16619. utility as a separate step of the program build.  %@NL@%
  16620. %@NL@%
  16621. If your program includes calls to API functions that are not in the FAPI
  16622. subset, you must use the /n option of the BIND utility, described in Section
  16623. 14.5, to build the dual-mode executable file. If you need to use the /n BIND
  16624. option, you cannot compile with /Fb. You must compile without linking by
  16625. using the /c option at the compile stage; then link the program and run the
  16626. BIND utility with the /n option.  %@NL@%
  16627. %@NL@%
  16628. %@NL@%
  16629. %@3@%%@CR:C6A00140017 @%%@AB@%14.2.3  Library Selection Options (/MT, /ML, /MD, /Zl)%@AE@%%@EH@%%@NL@%
  16630. %@NL@%
  16631. Special libraries are provided for building OS/2 multithread applications
  16632. and dynamic-link libraries. You must not use these libraries with any other
  16633. C run-time library.%@CR:C6A00140018 @%  %@NL@%
  16634. %@NL@%
  16635. %@AU@% Special libraries must be the only C run-time libraries linked with your
  16636. %@AU@%program.%@AE@%  %@NL@%
  16637. %@NL@%
  16638. If you use one of these special libraries, apply one of the library
  16639. selection options (/ML, /MD, or /MT) to tell the compiler to replace the
  16640. default library name in the object file with the name of the special
  16641. library. This ensures that the linker does not bring in code from the
  16642. default libraries. If you do not specify one of the options when compiling,
  16643. you must link with the /NOD option to prevent search of a default library,
  16644. such as SLIBCE.LIB.  %@NL@%
  16645. %@NL@%
  16646. If you fail to include any of these options, the linker searches the default
  16647. library and may select the wrong version of a library function. It might,
  16648. for example, select the single thread version of the %@AB@%printf%@AE@% function for a
  16649. multithread program that has more than one thread calling %@AB@%printf%@AE@%.  %@NL@%
  16650. %@NL@%
  16651. Because the /Lp option (see Section 14.2.1, "The Link Mode Options")
  16652. instructs the compiler to specify the default protected-mode libraries
  16653. rather than the special multithread or DLL-specific libraries, do not use it
  16654. with /Zl or /Mx.  %@NL@%
  16655. %@NL@%
  16656. %@NL@%
  16657. %@4@%%@AB@%Multithread Library Option (/MT)%@AE@%%@EH@%%@NL@%
  16658. %@NL@%
  16659. When you specify the /MT option, the compiler embeds the LLIBCMT.LIB
  16660. library name in the object file. Chapter 15, "Creating Multithread OS/2
  16661. Applications," explains how to build multithread applications using
  16662. LLIBCMT.LIB. The /MT option also has the effect of combining these
  16663. command-line options:  %@NL@%
  16664. %@NL@%
  16665. %@AS@%  /ALw /FPi /G2 /D MT%@AE@%%@NL@%
  16666. %@NL@%
  16667. %@NL@%
  16668. %@4@%%@AB@%C Run-Time Library for Building DLLs (/ML)%@AE@%%@EH@%%@NL@%
  16669. %@NL@%
  16670. Use the /ML option to specify that you are building a dynamic-link library
  16671. that calls functions in LLIBCDLL.LIB, the C run-time library for
  16672. dynamic-link  libraries. The library name is embedded in the object file.
  16673. The /ML option also has the effect of combining these command-line options:
  16674. %@NL@%
  16675. %@NL@%
  16676. %@AS@%  /ALw /FPa /G2 /D MT%@AE@%%@NL@%
  16677. %@NL@%
  16678. %@NL@%
  16679. %@4@%%@AB@%C Run-Time Library for DLLs (/MD)%@AE@%%@EH@%%@NL@%
  16680. %@NL@%
  16681. Use the /MD option to create a dynamic-link library of C run-time routines.
  16682. With this option, the object file does not have any library search records.
  16683. The /MD option has the effect of combining these command-line options:  %@NL@%
  16684. %@NL@%
  16685. %@AS@%  /ALw /FPi /G2 /DDLL /D MT%@AE@%%@NL@%
  16686. %@NL@%
  16687. Chapter 16, "Dynamic Linking with OS/2," describes the process of building
  16688. and using dynamic-link libraries with LLIBCDLL.LIB.  %@NL@%
  16689. %@NL@%
  16690. %@NL@%
  16691. %@4@%%@AB@%Suppress Default Library Option (/Zl)%@AE@%%@EH@%%@NL@%
  16692. %@NL@%
  16693. Use the /Zl option when you want to suppress selection of a default library.
  16694. It tells the compiler not to place the default library name in the object
  16695. file.%@CR:C6A00140019 @%  %@NL@%
  16696. %@NL@%
  16697. %@AU@% You can specify libraries and additional LINK options on the CL command
  16698. %@AU@%line.%@AE@%  %@NL@%
  16699. %@NL@%
  16700. You can specify link options or the names of libraries on the CL command
  16701. line with the /LINK option. You can also give the library name, with its
  16702. .LIB extension, before the /LINK option. Each command below selects the
  16703. multithread C run-time library:  %@NL@%
  16704. %@NL@%
  16705. %@AS@%  CL /Zl myprog.c llibcmt.lib
  16706. %@AS@%  
  16707. %@AS@%  CL /Zl myprog.c /link llibcmt%@AE@%%@NL@%
  16708. %@NL@%
  16709. If you compile with the /c (compile without link) option, your link command
  16710. must include the library name:  %@NL@%
  16711. %@NL@%
  16712. %@AS@%  LINK myprog, myprog.exe, myprog.map, llibcmt.lib, myprog.def%@AE@%%@NL@%
  16713. %@NL@%
  16714. %@NL@%
  16715. %@3@%%@CR:C6A00140020 @%%@AB@%14.2.4  Memory-Model Options (/Ax)%@AE@%%@EH@%%@NL@%
  16716. %@NL@%
  16717. You must select the memory model appropriate to your application. For
  16718. protected-mode applications, the large model provides the most convenient
  16719. interface with the special libraries. It provides the additional benefit of
  16720. placing code and data into multiple segments, allowing OS/2 to swap parts of
  16721. the program to disk efficiently.  %@NL@%
  16722. %@NL@%
  16723. %@AU@% Use the large memory model with LLIBCMT (/AL and /MT).%@AE@%  %@NL@%
  16724. %@NL@%
  16725. The multithread run-time C library, LLIBCMT.LIB, is a large-model library.
  16726. All library function calls must be far calls. In addition, all pointers
  16727. passed to functions in the library must be far pointers. If you do not
  16728. compile with the /AL option, you use must use the keyword %@AB@%_far%@AE@% when
  16729. declaring pointers. Variables can be declared either near or far as long as
  16730. they are either passed by value or cast to a far address.  %@NL@%
  16731. %@NL@%
  16732. If you want to call %@AB@%fopen %@AE@%for example, you must use code such as the
  16733. following:  %@NL@%
  16734. %@NL@%
  16735. %@AS@%  FILE _far * fp;
  16736. %@AS@%  fp = fopen( ... );%@AE@%%@NL@%
  16737. %@NL@%
  16738. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16739. NOTE
  16740.  
  16741. %@AI@%If you are using the compact, large, or huge memory model, data pointers are
  16742. %@AI@%far by default, so you do not need to explicitly specify %@AB@%_far%@AE@%%@AI@%.%@AE@%%@AE@%%@NL@%
  16743. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  16744. %@NL@%
  16745. %@AU@% Because each thread has its own stack, you have to compile in an SS != DS
  16746. %@AU@%model.%@AE@%  %@NL@%
  16747. %@NL@%
  16748. Multithread applications require that each thread have its own stack. As a
  16749. result, you cannot safely assume that the stack segment is in the default
  16750. data group (DGROUP). That means that the stack segment can be different from
  16751. the data segment (SS != DS).  %@NL@%
  16752. %@NL@%
  16753. To specify that you have selected an SS != DS model, you must use the /Au or
  16754. /Aw option. The /MT option is a shorthand way of specifying this combination
  16755. of options to the compiler:  %@NL@%
  16756. %@NL@%
  16757. %@AS@%  /ALw/FPi/G2/DMT%@AE@%%@NL@%
  16758. %@NL@%
  16759. The /MT option also causes the compiler to place a library search record for
  16760. LLIBCMT in the object file.  %@NL@%
  16761. %@NL@%
  16762. %@NL@%
  16763. %@2@%%@CR:C6A00140021 @%%@AB@%14.3  Module-Definition Files and Import Libraries%@AE@%%@EH@%%@NL@%
  16764. %@NL@%
  16765. A module-definition file tells the linker about the characteristics of an
  16766. application or dynamic-link library. It describes names, segments, memory
  16767. requirements, and import and export definitions. Export definitions make
  16768. functions in the OS/2 dynamic-link libraries (DLLs) available to other
  16769. programs. Each export definition specifies a function name. A program using
  16770. these functions must have import definitions in order to find each
  16771. dynamic-link function. Each import definition specifies a function name and
  16772. the name of the dynamic-link library where the function resides.  %@NL@%
  16773. %@NL@%
  16774. The IMPLIB utility generates a library of import definitions that can be
  16775. examined during the link. For imported functions, the import library can be
  16776. used in place of a module-definition file.  %@NL@%
  16777. %@NL@%
  16778. Module-definition files are optional for most OS/2 programs. Two types of
  16779. programs must use them:  %@NL@%
  16780. %@NL@%
  16781. %@NL@%
  16782.   ■   Dynamic-link libraries%@NL@%
  16783. %@NL@%
  16784.   ■   Programs with I/O privileges%@NL@%
  16785. %@NL@%
  16786. %@NL@%
  16787. Each module-definition file contains one or more module statements defining
  16788. attributes of the executable program. The statements and their associated
  16789. attributes are listed below:  %@NL@%
  16790. %@NL@%
  16791. %@AB@%Statement%@AE@%                         %@AB@%Attribute%@AE@%
  16792. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16793. %@AB@%CODE%@AE@%                              Gives default attributes for code 
  16794.                                   segments
  16795.  
  16796. %@AB@%DATA%@AE@%                              Gives default attributes for data 
  16797.                                   segments
  16798.  
  16799. %@AB@%DESCRIPTION%@AE@%                       Describes the module in one line
  16800.  
  16801. %@AB@%EXETYPE%@AE@%                           Identifies the operating system
  16802.  
  16803. %@AB@%EXPORTS%@AE@%                           Defines exported functions
  16804.  
  16805. %@AB@%HEAPSIZE%@AE@%                          Specifies local heap size, in bytes
  16806.  
  16807. %@AB@%IMPORTS%@AE@%                           Defines imported functions
  16808.  
  16809. %@AB@%LIBRARY%@AE@%                           Names a dynamic-link library
  16810.  
  16811. %@AB@%NAME%@AE@%                              Names an application
  16812.  
  16813. %@AB@%OLD%@AE@%                               Preserves import information from a 
  16814.                                   previous version of the library
  16815.  
  16816. %@AB@%PROTMODE%@AE@%                          Specifies that the module runs only in 
  16817.                                   OS/2 protected mode
  16818.  
  16819. %@AB@%REALMODE%@AE@%                          Relaxes some restrictions that the 
  16820.                                   linker imposes for protected-mode 
  16821.                                   programs
  16822.  
  16823. %@AB@%SEGMENTS%@AE@%                          Gives attributes for specific segments
  16824.  
  16825. %@AB@%STACKSIZE%@AE@%                         Specifies local stack size, in bytes
  16826.  
  16827. %@AB@%STUB%@AE@%                              Adds a DOS 3.x executable file to the 
  16828.                                   beginning of the module, usually to 
  16829.                                   terminate the program when run in real 
  16830.                                   mode
  16831.  
  16832. In addition to the keywords listed above, each statement includes one or
  16833. more fields to complete the attribute description. All keywords must be
  16834. entered in uppercase. You can include comments in the module-definition file
  16835. by beginning the line with a semicolon (;). For a complete list of the
  16836. keywords and their meaning, see on-line help for information about
  16837. module-definition files.  %@NL@%
  16838. %@NL@%
  16839. %@NL@%
  16840. %@3@%%@CR:C6A00140022 @%%@AB@%14.3.1  Adding a Module-Definition File to the LINK Command%@AE@%%@EH@%%@NL@%
  16841. %@NL@%
  16842. The module-definition file name is the last field of the link command:  %@NL@%
  16843. %@NL@%
  16844. %@AS@%  LINK objects «,«exe» » «, «map» » «, «lib» » «, «def» » «;»%@AE@%%@NL@%
  16845. %@NL@%
  16846. This example uses the default libraries:  %@NL@%
  16847. %@NL@%
  16848. %@AS@%  LINK sample, sample.exe, sample.map,,sample.def%@AE@%%@NL@%
  16849. %@NL@%
  16850. When you use a module-definition file, you must use the /c option on the CL
  16851. command line and link in a separate step. If you are linking without a
  16852. module-definition file, you can use a semicolon after your last entry to
  16853. suppress LINK's prompt for the module-definition file name and other missing
  16854. parameters.  %@NL@%
  16855. %@NL@%
  16856. The segmented-executable linker is the only LINK program that recognizes
  16857. module-definition files. Since it is backwards compatible, it should be the
  16858. only linker in your path. The QuickC linker does not process these files.  %@NL@%
  16859. %@NL@%
  16860. The following sections illustrate ways to use module-definition files.
  16861. On-line help describes all of the commands and options available.  %@NL@%
  16862. %@NL@%
  16863. %@NL@%
  16864. %@3@%%@CR:C6A00140023 @%%@AB@%14.3.2  Creating Dynamic-Link Libraries (DLLs)%@AE@%%@EH@%%@NL@%
  16865. %@NL@%
  16866. You can build your own dynamic-link libraries. A simple module-definition
  16867. file for such a library with one public function is shown below:%@CR:C6A00140024 @%  %@NL@%
  16868. %@NL@%
  16869. %@AS@%  LIBRARY Mylib INITINSTANCE
  16870. %@AS@%  
  16871. %@AS@%  DATA MULTIPLE
  16872. %@AS@%  
  16873. %@AS@%  EXPORTS
  16874. %@AS@%   MyProc%@AE@%%@NL@%
  16875. %@NL@%
  16876. You can use the same module-definition file you used to create the
  16877. dynamic-link library as input to the IMPLIB utility. IMPLIB generates a
  16878. library file with a .LIB extension for use by applications calling your
  16879. dynamic-link routines. Section 14.3.5 describes the IMPLIB program. Chapter
  16880. 16, "Dynamic Linking with OS/2," explains how to build a dynamic-link
  16881. library.  %@NL@%
  16882. %@NL@%
  16883. The %@AB@%LIBRARY%@AE@% statement tells the linker that this is a dynamic-link library
  16884. rather than an application. (Applications use the %@AB@%NAME%@AE@% statement instead of
  16885. the %@AB@%LIBRARY%@AE@% statement.)  %@NL@%
  16886. %@NL@%
  16887. The %@AB@%EXPORTS%@AE@% statement gives the name of the public function.  %@NL@%
  16888. %@NL@%
  16889. %@AU@% You can designate exported functions in a C source file.%@AE@%  %@NL@%
  16890. %@NL@%
  16891. The C language keyword %@AB@%_export%@AE@% is an alternative to the %@AB@%EXPORTS%@AE@% statement.
  16892. When %@AB@%_export%@AE@% appears in a function declaration or definition, the compiler
  16893. puts the function and its parameter size in the object module's export
  16894. record. Functions with the %@AB@%_export%@AE@% keyword that are not listed in the
  16895. module-definition file cannot have input/output privileges or alias names.  %@NL@%
  16896. %@NL@%
  16897. %@AU@% Using generic library names is dangerous.%@AE@%  %@NL@%
  16898. %@NL@%
  16899. Since OS/2 systems have many dynamic-link libraries installed, try to pick a
  16900. name that uniquely identifies your library. If you choose a generic name,
  16901. such as CRT.DLL or WINDOWS.DLL, you run the risk of having your library
  16902. overwritten by someone else's dynamic-link library with the same name.  %@NL@%
  16903. %@NL@%
  16904. %@NL@%
  16905. %@3@%%@CR:C6A00140025 @%%@AB@%14.3.3  Creating Programs with I/O Privileges%@AE@%%@EH@%%@NL@%
  16906. %@NL@%
  16907. OS/2 programs that must access hardware directly can designate a code
  16908. segment with input/output privileges. This segment can then perform a
  16909. limited set of I/O instructions but cannot make any calls to dynamic-link
  16910. libraries.  %@NL@%
  16911. %@NL@%
  16912. You cannot use the C run-time library functions %@AB@%inp%@AE@% and %@AB@%outp%@AE@% for input and
  16913. output. Their use is limited to real-mode programs. You can, however, use
  16914. in-line assembler code in your C source program to access a port.  %@NL@%
  16915. %@NL@%
  16916. The sample module-definition file below shows two segments for a program:  %@NL@%
  16917. %@NL@%
  16918. %@AS@%  NAME         IOPROG
  16919. %@AS@%  
  16920. %@AS@%  EXETYPE         OS/2
  16921. %@AS@%  
  16922. %@AS@%  SEGMENTS     
  16923. %@AS@%       _IOSEG      IOPL
  16924. %@AS@%       _TEXT       NOIOPL
  16925. %@AS@%  
  16926. %@AS@%  EXPORTS
  16927. %@AS@%       CharIn      4
  16928. %@AS@%       CharOut     4%@AE@%%@NL@%
  16929. %@NL@%
  16930. The first code segment contains the I/O portion of the program and has the
  16931. %@AB@%IOPL %@AE@%keyword. The second segment is designated %@AB@%NOIOPL %@AE@%(the default).  %@NL@%
  16932. %@NL@%
  16933. %@AU@% The EXPORT statement for IOPL functions must include parameter size.%@AE@%  %@NL@%
  16934. %@NL@%
  16935. The %@AB@%EXPORTS %@AE@%section names two functions in the %@AB@%IOPL%@AE@% segment that can be
  16936. called by procedures outside the segment. It also specifies the size of the
  16937. function's parameters. Procedures with I/O privileges must specify the
  16938. number of words needed for their parameters.  %@NL@%
  16939. %@NL@%
  16940. ────────────────────────────────────────────────────────────────────────────%@NL@%
  16941. NOTE
  16942.  
  16943. %@AI@%Unless the user has specified IOPL=YES in the CONFIG.SYS file, the program
  16944. %@AI@%will not load.%@AE@%%@NL@%
  16945. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  16946. %@NL@%
  16947. %@NL@%
  16948. %@3@%%@CR:C6A00140026 @%%@AB@%14.3.4  Creating Presentation Manager Applications%@AE@%%@EH@%%@NL@%
  16949. %@NL@%
  16950. The Presentation Manager calls window and dialog procedures inside a
  16951. Presentation Manager application. The sample module-definition file below
  16952. exports these procedures and gives the linker additional instructions for
  16953. building the program. Module-definition files are optional for Presentation
  16954. Manager applications. They can be used to control the way different segments
  16955. of the program are loaded.  %@NL@%
  16956. %@NL@%
  16957. %@AS@%  NAME         PMSAMPLE    WINDOWAPI
  16958. %@AS@%  
  16959. %@AS@%  EXETYPE          OS/2
  16960. %@AS@%  STACKSIZE        4096
  16961. %@AS@%  
  16962. %@AS@%  SEGMENTS
  16963. %@AS@%       _INIT       PRELOAD
  16964. %@AS@%       _HELP       LOADONCALL
  16965. %@AS@%       _TEXT       LOADONCALL%@AE@%%@NL@%
  16966. %@NL@%
  16967. In the preceding example, the %@AB@%NAME %@AE@%statement identifies the program as an
  16968. application named PMSAMPLE. The %@AB@%WINDOWAPI %@AE@%keyword tells the linker to mark
  16969. the executable file as a Presentation Manager application. Only programs
  16970. marked as windows applications or windows-compatible applications can share
  16971. the Presentation Manager screen group.  %@NL@%
  16972. %@NL@%
  16973. The %@AB@%EXETYPE %@AE@%statement tells the linker to build a program that runs only in
  16974. protected mode and to produce the optimal executable file for OS/2.  %@NL@%
  16975. %@NL@%
  16976. The %@AB@%STACKSIZE %@AE@%statement allocates 4096 bytes of local stack space. This is
  16977. the minimum stack size recommended for Presentation Manager programs.  %@NL@%
  16978. %@NL@%
  16979. %@AU@% You can reduce run-time memory requirements.%@AE@%  %@NL@%
  16980. %@NL@%
  16981. The %@AB@%SEGMENTS %@AE@%statement controls the way code and data segments are handled.
  16982. By default, segments are not brought into physical memory until needed. The
  16983. %@AB@%PRELOAD %@AE@%keyword in the example tells the system loader to load the %@AS@% _INIT %@AE@%
  16984. segment when the program starts. The %@AS@% _TEXT %@AE@% and %@AS@% _HELP %@AE@% segments are loaded
  16985. on demand. You can use the compiler's /NT option to generate your own
  16986. segment names, such as %@AS@% _INIT %@AE@% and %@AS@% _HELP%@AE@%. Separate segments are useful for
  16987. code that is executed infrequently, such as a help subsystem. This reduces
  16988. the amount of run-time memory required for your application, since each
  16989. segment will be loaded when and if there is a request for it.  %@NL@%
  16990. %@NL@%
  16991. %@NL@%
  16992. %@3@%%@CR:C6A00140027 @%%@AB@%14.3.5  Creating Import Libraries with the IMPLIB Utility%@AE@%%@EH@%%@NL@%
  16993. %@NL@%
  16994. Applications that call dynamic-link library functions must use import
  16995. definitions that specify the location of each dynamic-link function. The
  16996. definitions consist of a function name and the name of the dynamic-link
  16997. library file where it resides.%@CR:C6A00140028 @%  %@NL@%
  16998. %@NL@%
  16999. Although the application can use a module-definition file to create the
  17000. import definitions, it is easier to use import libraries built by the IMPLIB
  17001. utility.  %@NL@%
  17002. %@NL@%
  17003. IMPLIB creates an import library in the form of a file with a .LIB
  17004. extension, which is read by the linker. At link time, the .LIB file is
  17005. specified in the LINK command line, along with other libraries.  %@NL@%
  17006. %@NL@%
  17007. IMPLIB accepts two types of sources:  %@NL@%
  17008. %@NL@%
  17009. %@NL@%
  17010.   ■   The module-definition file used to create the dynamic-link library%@NL@%
  17011. %@NL@%
  17012.   ■   The dynamic-link library itself%@NL@%
  17013. %@NL@%
  17014. %@NL@%
  17015. The IMPLIB command has the syntax:  %@NL@%
  17016. %@NL@%
  17017. %@AS@%  IMPLIB «/c»libfile deffile  «deffile ...»%@AE@%%@NL@%
  17018. %@NL@%
  17019. or  %@NL@%
  17020. %@NL@%
  17021. %@AS@%  IMPLIB  «/c»libfile dynlib «dynlib ...»%@AE@%%@NL@%
  17022. %@NL@%
  17023. The /c option directs IMPLIB to be case sensitive. By default, it is case
  17024. insensitive.  %@NL@%
  17025. %@NL@%
  17026. The %@AI@%libfile %@AE@%field names the new import library file. The %@AI@%deffile %@AE@%or %@AI@%dynlib
  17027. %@AI@%%@AE@%fields name the input files, which are dynamic-link library or
  17028. module-definition files.  %@NL@%
  17029. %@NL@%
  17030. The following example creates the import library file named MYLIB.LIB from
  17031. the MYLIB.DLL dynamic-link library:  %@NL@%
  17032. %@NL@%
  17033. %@AS@%  IMPLIB mylib.lib mylib.dll%@AE@%%@NL@%
  17034. %@NL@%
  17035. For more information about import libraries and IMPLIB, consult on-line
  17036. help.  %@NL@%
  17037. %@NL@%
  17038. %@NL@%
  17039. %@2@%%@CR:C6A00140029 @%%@AB@%14.4  Link Command-Line Options%@AE@%%@EH@%%@NL@%
  17040. %@NL@%
  17041. This section describes command-line options that control various aspects of
  17042. the linker and the circumstances in which you will need to use them.%@CR:C6A00140030 @%%@CR:C6A00140031 @%  %@NL@%
  17043. %@NL@%
  17044. %@NL@%
  17045. %@4@%%@AB@%/NODEFAULTLIBRARYSEARCH (/NOD)%@AE@%%@EH@%%@NL@%
  17046. %@NL@%
  17047. %@AU@% If you did not compile with /MT, /MD, or /ML, suppress default library
  17048. %@AU@%searching.%@AE@%  %@NL@%
  17049. %@NL@%
  17050. The /NODEFAULTLIBRARYSEARCH option prevents the linker from searching any
  17051. library specified in an object file. When you specify this option, you
  17052. should also specify the name of the library to be linked. The minimum
  17053. abbreviation for this option is /NOD.  %@NL@%
  17054. %@NL@%
  17055. If you are using the multithread library, LLIBCMT, or the dynamic-link
  17056. library, LLIBCDLL, you should use this option. Use it with dynamic-link
  17057. libraries built with LLIBCDLL. This is mandatory if you did not compile with
  17058. the /Zl, /MT, or /ML options.  %@NL@%
  17059. %@NL@%
  17060. You can select a specific library by appending the library name to the /NOD
  17061. option, as in  %@NL@%
  17062. %@NL@%
  17063. %@AS@%  /NOD:LLIBCMT.LIB%@AE@%%@NL@%
  17064. %@NL@%
  17065. %@NL@%
  17066. %@4@%%@AB@%/NOEXTENDEDDICTSEARCH (/NOE)%@AE@%%@EH@%%@NL@%
  17067. %@NL@%
  17068. The /NOEXTENDEDDICTSEARCH option prevents the linker from searching the
  17069. extended dictionary, which is an internal list of symbol locations
  17070. maintained by the linker. You need to use this option if a library symbol
  17071. (such as %@AB@%_setargv%@AE@%, %@AB@%_binmode%@AE@%, or %@AB@%_varstck%@AE@%) is redefined and you receive error
  17072. L2044 from the linker. The minimum abbreviation for this option is /NOE.%@CR:C6A00140032 @%%@CR:C6A00140033 @%  %@NL@%
  17073. %@NL@%
  17074. %@NL@%
  17075. %@4@%%@AB@%/NOIGNORECASE (/NOI)%@AE@%%@EH@%%@NL@%
  17076. %@NL@%
  17077. The /NOIGNORECASE option preserves case sensitivity. By default, LINK maps
  17078. all names to uppercase characters. Because many C function names are a mix
  17079. of upper- and lowercase letters, it is important to use this option. The
  17080. compile option /Zc causes any name declared with the %@AB@%_pascal%@AE@% keyword to be
  17081. treated without regard to case at the source level. The minimum abbreviation
  17082. is /NOI.  %@NL@%
  17083. %@NL@%
  17084. %@NL@%
  17085. %@4@%%@AB@%/PMTYPE%@AE@%%@EH@%%@NL@%
  17086. %@NL@%
  17087. The /PMTYPE option is an alternative to specifying Presentation Manager
  17088. compatibility with the %@AB@%NAME%@AE@% statement of a module-definition file. Use the
  17089. following syntax:  %@NL@%
  17090. %@NL@%
  17091. %@AS@%  /PMTYPE:type%@AE@%%@NL@%
  17092. %@NL@%
  17093. Type must be one of the following:  %@NL@%
  17094. %@NL@%
  17095. %@AB@%Type%@AE@%                              %@AB@%Effect%@AE@%
  17096. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17097. %@AB@%PM%@AE@%                                The application is an OS/2 Presentation 
  17098.                                   Manager application using the 
  17099.                                   Presentation Manager API and running in 
  17100.                                   the Presentation Manager screen group. 
  17101.                                   This type corresponds to specifying %@AB@%%@AE@%
  17102.                                   %@AB@%WINDOWAPI%@AE@% in the %@AB@%NAME%@AE@% statement of a 
  17103.                                   module-definition file.
  17104.  
  17105. %@AB@%VIO%@AE@%                               The application is compatible with the 
  17106.                                   OS/2 Presentation Manager and can run in
  17107.                                   a window or in a
  17108.                                   separate screen group. This type 
  17109.                                   corresponds to specifying %@AB@%WINDOWCOMPAT%@AE@% 
  17110.                                   in the %@AB@%NAME %@AE@%statement of a 
  17111.                                   module-definition file.
  17112.  
  17113. %@AB@%NOVIO%@AE@%                             The application is not compatible with 
  17114.                                   the OS/2
  17115.                                   Presentation Manager. It must run in a 
  17116.                                   separate
  17117.                                   screen group. This type corresponds to 
  17118.                                   specifying%@AB@%%@AE@%
  17119.                                   %@AB@%NOTWINDOWCOMPAT%@AE@% in the %@AB@%NAME%@AE@% statement of
  17120.                                   a module-definition file.
  17121.  
  17122. %@NL@%
  17123. %@2@%%@CR:C6A00140034 @%%@AB@%14.5  The BIND Utility%@AE@%%@EH@%%@NL@%
  17124. %@NL@%
  17125. The BIND utility converts a protected-mode program into a program that runs
  17126. in both OS/2 and DOS environments. It replaces Family API calls to
  17127. dynamic-link library functions with DOS emulator routines from the API.LIB
  17128. library. (See Section 14.1.3, "Creating Dual-Mode Programs as Family
  17129. Applications," for a list of Family API calls.) BIND produces a stand-alone
  17130. program file that can run under  %@NL@%
  17131. %@NL@%
  17132. %@NL@%
  17133.   ■   OS/2 protected mode%@NL@%
  17134. %@NL@%
  17135.   ■   OS/2 real mode%@NL@%
  17136. %@NL@%
  17137.   ■   DOS 2.x and DOS 3.x%@NL@%
  17138. %@NL@%
  17139. %@NL@%
  17140. BIND is an alternative to the C compiler's /Fb option described in Section
  17141. 14.2.2, "Creating Bound Programs Option." You must use BIND instead of the
  17142. /Fb option when you compile with the /c (compile without link) option or
  17143. when your program includes functions that operate only in protected mode.  %@NL@%
  17144. %@NL@%
  17145. %@AU@% You can include functions in a bound application that are not members of
  17146. %@AU@%the Family API.%@AE@%  %@NL@%
  17147. %@NL@%
  17148. To include functions available only in protected mode, you must run the BIND
  17149. utility with the /n option. Your run-time code must call the Family API
  17150. function %@AB@%DosGetMachineMode%@AE@% to determine whether it is running in real or
  17151. protected mode. When your program executes in real mode, it will be aborted
  17152. if it tries to call a function available only in protected mode.  %@NL@%
  17153. %@NL@%
  17154. You might choose to design your application so it executes different
  17155. sections of code, depending on the machine mode. For example, the
  17156. application may need to keep track of the passage of elapsed time or to
  17157. detect time-outs. In real mode, you might use polling or timing loops or
  17158. perhaps intercept the timer interrupts. In protected mode, you should use
  17159. the OS/2 semaphore and timer services, such as %@AB@%DosSetSem%@AE@% and %@AB@%DosTimerAsync%@AE@%,
  17160. instead.  %@NL@%
  17161. %@NL@%
  17162. Invoke BIND with the following syntax:  %@NL@%
  17163. %@NL@%
  17164. %@AS@%  BIND infile «implibs» «linklibs» «/o outfile» «/n @file» «/n names» 
  17165. %@AS@%  «/m mapfile»%@AE@%%@NL@%
  17166. %@NL@%
  17167. The /n option provides a way to include protected-mode functions. It has two
  17168. formats:  %@NL@%
  17169. %@NL@%
  17170. %@NL@%
  17171.   ■   A list of one or more names, separated by spaces.%@NL@%
  17172. %@NL@%
  17173.   ■   The name of a file, preceded by the at (@) sign. The file should
  17174.       consist of a list of functions, one name per line.%@NL@%
  17175. %@NL@%
  17176. %@NL@%
  17177. The /o option specifies a name for the bound-executable file. If it is not
  17178. present, the name of the input file is used.  %@NL@%
  17179. %@NL@%
  17180. The /m option causes a link map to be generated for the real-mode version of
  17181. the executable file.  %@NL@%
  17182. %@NL@%
  17183. To bind a program named TIMER that uses %@AB@%DosTimerAsync%@AE@% to manage time-outs
  17184. when running in protected mode, invoke BIND as follows:  %@NL@%
  17185. %@NL@%
  17186. %@AS@%  BIND TIMER /n DosTimerAsync%@AE@%%@NL@%
  17187. %@NL@%
  17188. For more information about BIND and other command-line options, consult
  17189. on-line help.  %@NL@%
  17190. %@NL@%
  17191. %@NL@%
  17192. %@NL@%
  17193. %@NL@%
  17194. %@NL@%
  17195. %@NL@%
  17196. %@CR:C6A00150001 @%%@1@%%@AB@%Chapter 15  Creating Multithread OS/2 Applications%@AE@%%@EH@%%@NL@%
  17197. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17198. %@NL@%
  17199. Microsoft C, version 6.0, provides support for creating multithread
  17200. applications under OS/2. You should consider using more than one thread if
  17201. your application needs to manage multiple activities, such as simultaneous
  17202. keyboard and mouse input. One thread can process keyboard input while a
  17203. second thread filters mouse activities. A third thread could update the
  17204. display screen based on data from the mouse and keyboard threads. At the
  17205. same time, other threads can access disk files or get data from a
  17206. communications port.  %@NL@%
  17207. %@NL@%
  17208. This chapter explains the features in C 6.0 that support the creation of
  17209. multithread programs. It also describes some important ways in which
  17210. programming for OS/2 is different than programming for DOS.  %@NL@%
  17211. %@NL@%
  17212. %@NL@%
  17213. %@2@%%@CR:C6A00150002 @%%@AB@%15.1  Multithread Programs%@AE@%%@EH@%%@NL@%
  17214. %@NL@%
  17215. OS/2 performs the scheduling and allocation of real hardware resources to
  17216. multiple programs, or "processes." It does not actually schedule the
  17217. processes themselves; it schedules threads belonging to the processes.  %@NL@%
  17218. %@NL@%
  17219. A thread is basically a path of execution through a program. It is also the
  17220. smallest unit of execution that OS/2 schedules. A thread consists of a
  17221. stack, the state of the CPU registers, and an entry in the execution list of
  17222. the system scheduler. Each thread shares all of the process's resources.  %@NL@%
  17223. %@NL@%
  17224. A process consists of one or more threads and the code, data, and other
  17225. resources of a program in memory. Typical program resources are open files,
  17226. semaphores, and dynamically allocated memory. A program executes when the
  17227. system scheduler gives one of its threads execution control. The scheduler
  17228. determines which threads should run and when they should run. Threads of
  17229. lower priority may have to wait while higher priority threads complete their
  17230. tasks.  %@NL@%
  17231. %@NL@%
  17232. %@AU@% Threads operate  independently and are  unaware of other threads.%@AE@%  %@NL@%
  17233. %@NL@%
  17234. All threads in a process operate independently of one another. Unless you
  17235. take special steps to make them visible to each other, each thread executes
  17236. while completely unaware of the existence of other threads in a process.
  17237. Threads sharing common resources, however, must coordinate their work by
  17238. using flags, semaphores or some other method of interprocess communication.
  17239. See Section 15.3, "Writing a Multithread Program," for more information
  17240. about synchronizing threads.  %@NL@%
  17241. %@NL@%
  17242. %@NL@%
  17243. %@3@%%@CR:C6A00150003 @%%@AB@%15.1.1  Library Support%@AE@%%@EH@%%@NL@%
  17244. %@NL@%
  17245. %@AU@% All shared functions  in a multithread  program must be re-entrant.%@AE@%  %@NL@%
  17246. %@NL@%
  17247. If one thread is suspended by the OS/2 scheduler while executing the %@AB@%printf%@AE@%
  17248. function, one of the program's other threads might start executing. If the
  17249. second thread also calls %@AB@%printf%@AE@%, data might be corrupted. To avoid this,
  17250. access to static data used by the function must be restricted to one thread
  17251. at a time. This process of restricting access to certain data is called
  17252. serialization.  %@NL@%
  17253. %@NL@%
  17254. You do not need to serialize access to stack-based (automatic) variables
  17255. because each thread has a different stack. Therefore, a function that uses
  17256. only automatic (stack) variables is re-entrant. The standard C run-time
  17257. libraries, such as SLIBCE, have a limited number of re-entrant functions. A
  17258. multithread program needing to use C run-time library functions that are
  17259. normally not re-entrant should be built with the multithread library
  17260. LLIBCMT.LIB.  %@NL@%
  17261. %@NL@%
  17262. %@NL@%
  17263. %@4@%%@AB@%The Multithread C Library LLIBCMT.LIB%@AE@%%@EH@%%@NL@%
  17264. %@NL@%
  17265. The support library LLIBCMT.LIB is a re-entrant large-model library for
  17266. cre-ating multithread programs.  %@NL@%
  17267. %@NL@%
  17268. %@AU@% A multithread program  linked with LLIBCMT.LIB can  use any memory model.%@AE@%  %@NL@%
  17269. %@NL@%
  17270. All calls to library functions must use the large-model calling interface
  17271. (far code pointers, far calls, and far data pointers). When your application
  17272. calls functions in this library,  %@NL@%
  17273. %@NL@%
  17274. %@NL@%
  17275.   ■   All library calls must be far calls.%@NL@%
  17276. %@NL@%
  17277.   ■   All library calls must use the C calling convention; programs compiled
  17278.       using the /Gr (fastcall calling convention) or /Gc (Pascal calling
  17279.       convention) options must use the standard include files for the
  17280.       run-time library functions they call.%@NL@%
  17281. %@NL@%
  17282.   ■   All data and code pointers must be far pointers.%@NL@%
  17283. %@NL@%
  17284.   ■   Variables passed to library functions must either be passed by value
  17285.       or cast to a far address.%@NL@%
  17286. %@NL@%
  17287.   ■   Your main function must be declared far if you are compiling with the
  17288.       small or compact memory models.%@NL@%
  17289. %@NL@%
  17290. %@NL@%
  17291. You do not need to explicitly declare far pointers if you are using the
  17292. compact, large, or huge memory models, since these models use far pointers
  17293. as default. For the large and huge memory models, the function calls are
  17294. also far by default.  %@NL@%
  17295. %@NL@%
  17296. A small-model program calling a library function such as %@AB@%isupper%@AE@%, for
  17297. example, must use declarations like the following:  %@NL@%
  17298. %@NL@%
  17299. %@AS@%  int _far _cdecl isupper( int _c );%@AE@%%@NL@%
  17300. %@NL@%
  17301. %@AU@% Programs built with LLIBCMT.LIB are entirely self-contained.%@AE@%  %@NL@%
  17302. %@NL@%
  17303. Programs built with LLIBCMT.LIB do not share C run-time library code or data
  17304. with any dynamic-link libraries they call. Chapter 16 explains how to build
  17305. DLLs and how to share code and data between processes.  %@NL@%
  17306. %@NL@%
  17307. %@NL@%
  17308. %@4@%%@AB@%Alternatives to LLIBCMT.LIB%@AE@%%@EH@%%@NL@%
  17309. %@NL@%
  17310. If you choose to build a multithread program without using LLIBCMT.LIB, you
  17311. must do the following:  %@NL@%
  17312. %@NL@%
  17313. %@NL@%
  17314.   ■   Use the standard C libraries and limit library calls to the set of
  17315.       re-entrant functions.%@NL@%
  17316. %@NL@%
  17317.   ■   Use the OS/2 API thread management functions, such as %@AB@%DosCreateThread%@AE@%.%@NL@%
  17318. %@NL@%
  17319.   ■   Provide your own synchronization for functions that are not re-entrant
  17320.       by using OS/2 services such as semaphores and the %@AB@%DosEnterCritSec%@AE@% and
  17321.       %@AB@%DosExitCritSec%@AE@% functions.%@NL@%
  17322. %@NL@%
  17323. %@NL@%
  17324. The C run-time library functions listed below are re-entrant and can be used
  17325. in multithread programs linked with the standard libraries.  %@NL@%
  17326. %@NL@%
  17327. %@AB@%abs%@AE@%
  17328. %@AB@%atoi%@AE@%
  17329. %@AB@%atol%@AE@%
  17330. %@AB@%bsearch%@AE@%
  17331. %@AB@%chdir%@AE@%
  17332. %@AB@%getpid%@AE@%
  17333. %@AB@%halloc%@AE@%
  17334. %@AB@%hfree%@AE@%
  17335. %@AB@%itoa%@AE@%
  17336. %@AB@%labs%@AE@%
  17337. %@AB@%lfind%@AE@%
  17338. %@AB@%lsearch%@AE@%
  17339. %@AB@%memccpy%@AE@%
  17340. %@AB@%memchr%@AE@%
  17341. %@AB@%memcmp%@AE@%
  17342. %@AB@%memcpy%@AE@%
  17343. %@AB@%memicmp%@AE@%
  17344. %@AB@%memmove%@AE@%
  17345. %@AB@%memset%@AE@%
  17346. %@AB@%mkdir%@AE@%
  17347. %@AB@%movedata%@AE@%
  17348. %@AB@%putch%@AE@%
  17349. %@AB@%rmdir%@AE@%
  17350. %@AB@%segread%@AE@%
  17351. %@AB@%strcat%@AE@%
  17352. %@AB@%strchr%@AE@%
  17353. %@AB@%strcmp%@AE@%
  17354. %@AB@%strcmpi%@AE@%
  17355. %@AB@%strcpy%@AE@%
  17356. %@AB@%stricmp%@AE@%
  17357. %@AB@%strlen%@AE@%
  17358. %@AB@%strlwr%@AE@%
  17359. %@AB@%strncat%@AE@%
  17360. %@AB@%strncmp%@AE@%
  17361. %@AB@%strncpy%@AE@%
  17362. %@AB@%strnicmp%@AE@%
  17363. %@AB@%strnset%@AE@%
  17364. %@AB@%strrchr%@AE@%
  17365. %@AB@%strrev%@AE@%
  17366. %@AB@%strset%@AE@%
  17367. %@AB@%strstr%@AE@%
  17368. %@AB@%strupr%@AE@%
  17369. %@AB@%swab%@AE@%
  17370. %@AB@%tolower%@AE@%
  17371. %@AB@%toupper%@AE@%
  17372. %@AB@%──────────────────────────────────────────%@AE@%
  17373.  
  17374. %@AU@%WARNING%@AE@%%@NL@%
  17375. %@NL@%
  17376. The multithread library LLIBCMT.LIB includes the %@AB@%%@AE@%%@AI@%_beginthread%@AE@% and %@AB@%%@AE@%%@AI@%_endthread%@AE@%
  17377. functions. The %@AB@%%@AE@%%@AI@%_beginthread%@AE@% function performs initialization without which
  17378. many C run-time functions will fail. You must use %@AB@%%@AE@%%@AI@%_beginthread%@AE@% instead of
  17379. %@AB@%%@AE@%%@AI@%DosCreateThread%@AE@% in C programs built with LLIBCMT.LIB if you intend to call C
  17380. run-time functions.%@NL@%
  17381. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17382. %@NL@%
  17383. %@NL@%
  17384. %@4@%%@AB@%The Multithread Library Compile Option (/MT)%@AE@%%@EH@%%@NL@%
  17385. %@NL@%
  17386. The /MT option for the CL command is the best way to build a multithread
  17387. program with LLIBCMT.LIB. The /MT option embeds the LLIBCMT library name in
  17388. the object file. Using the /MT option automatically specifies the /ALw /FPi
  17389. /G2 /D MT options. The following list describes what these options do.  %@NL@%
  17390. %@NL@%
  17391. %@AB@%Switch%@AE@%                            %@AB@%Effect%@AE@%
  17392. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17393. /ALw                              Use the large memory model with separate
  17394.                                   stack segment; do not reload the DS 
  17395.                                   register as part of the entry sequence 
  17396.                                   for every function
  17397.  
  17398. /FPi                              Generate in-line floating-point 
  17399.                                   instructions and select the emulator 
  17400.                                   math package
  17401.  
  17402. /G2                               Use the 80286 processor instruction set
  17403.  
  17404. /D MT                             Use the multithread version of the 
  17405.                                   include files
  17406.  
  17407. These options can be combined with other options to specify different memory
  17408. models and different relationships between the data segment and the stack.
  17409. You can override the /G2 and /FPi options by specifying a different option
  17410. later on the command line. The following example shows how to override the
  17411. floating-point package option:  %@NL@%
  17412. %@NL@%
  17413. %@AS@%  CL /MT /FPa /Lp PROG.C%@AE@%%@NL@%
  17414. %@NL@%
  17415. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17416. NOTE
  17417.  
  17418. %@AI@%You cannot replace the /MT option with /ALw /FPi /G2. You must use /MT to
  17419. %@AI@%generate multithread programs.%@AE@%%@NL@%
  17420. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  17421. %@NL@%
  17422. %@NL@%
  17423. %@3@%%@CR:C6A00150004 @%%@AB@%15.1.2  Include Files%@AE@%%@EH@%%@NL@%
  17424. %@NL@%
  17425. The Microsoft C 6.0 include files contain conditional sections for
  17426. multithread applications using LLIBCMT.LIB. To compile your application with
  17427. the appropriate definitions, you can  %@NL@%
  17428. %@NL@%
  17429. %@NL@%
  17430.   ■   Compile with the /MT option described in Section 15.1.1, "Library
  17431.       Support."%@NL@%
  17432. %@NL@%
  17433.   ■   Define the symbolic constant %@AB@%MT%@AE@% in your source file or on the command
  17434.       line with the /D option.%@NL@%
  17435. %@NL@%
  17436. %@NL@%
  17437. %@AU@% Always use the  standard include files.%@AE@%  %@NL@%
  17438. %@NL@%
  17439. Standard include files declare C run-time library functions as they are
  17440. implemented in the libraries. If you used the Maximum Optimization (/Ox) or
  17441. Register Calling Convention (/Gr) option, the compiler assumes that all
  17442. functions should be called using the register calling convention. The
  17443. run-time library functions were compiled using either the C or the
  17444. FORTRAN/Pascal calling convention, and the declarations in the standard
  17445. include files tell the compiler to generate correct external references to
  17446. these functions.  %@NL@%
  17447. %@NL@%
  17448. See Section 15.4, "Compiling and Linking," for examples of how to use the%@AB@% MT%@AE@%
  17449. constant.  %@NL@%
  17450. %@NL@%
  17451. %@NL@%
  17452. %@3@%%@CR:C6A00150005 @%%@AB@%15.1.3  C Run-Time Library Functions for Thread Control%@AE@%%@EH@%%@NL@%
  17453. %@NL@%
  17454. All OS/2 programs have at least one thread. Any thread can create additional
  17455. threads. A thread can complete its work very quickly and then terminate, or
  17456. it can stay active for the life of the program.  %@NL@%
  17457. %@NL@%
  17458. The LLIBCMT and LLIBCDLL C run-time libraries provide two functions for
  17459. thread creation and termination: the %@AB@%_beginthread%@AE@% and %@AB@%_endthread%@AE@% functions.
  17460. They also declare the global variable %@AB@%_threadid%@AE@%, which contains the address
  17461. of an application's current thread identifier.  %@NL@%
  17462. %@NL@%
  17463. The %@AB@%_beginthread%@AE@% function creates a new thread and returns a thread
  17464. identifier if the operation is successful. The thread will terminate
  17465. automatically if it completes execution, or it can terminate itself with a
  17466. call to %@AB@%_endthread%@AE@%.  %@NL@%
  17467. %@NL@%
  17468. The global variable %@AB@%_threadid%@AE@% holds the address of the identifier of the
  17469. current thread. It is defined in the STDDEF.H file as shown below:  %@NL@%
  17470. %@NL@%
  17471. %@AS@%  /* define pointer to thread id value */
  17472. %@AS@%  extern int far * _threadid;%@AE@%%@NL@%
  17473. %@NL@%
  17474. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17475. %@AU@%WARNING%@AE@%%@NL@%
  17476. %@NL@%
  17477. If you are going to call C run-time routines from a program built with
  17478. LLIBCMT.LIB, you must start your threads with the %@AB@%%@AE@%%@AI@%_beginthread%@AE@% function. Do
  17479. not use the OS/2 functions %@AB@%%@AE@%%@AI@%DosExit%@AE@% %@AB@% %@AE@%and %@AB@%DosCreateThread%@AE@%.%@AB@%%@AE@%%@AI@% %@AE@%Using
  17480. %@AB@%%@AE@%%@AI@%DosSuspendThread%@AE@% can lead to a deadlock condition when more than one thread
  17481. is blocked waiting for the suspended thread to complete its access to a C
  17482. run-time data structure.%@NL@%
  17483. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17484. %@NL@%
  17485. The %@AB@%_beginthread%@AE@% and %@AB@%_endthread%@AE@% functions are described in detail below.
  17486. Section 15.2 illustrates their use in a sample multithread program.  %@NL@%
  17487. %@NL@%
  17488. %@NL@%
  17489. %@4@%%@AB@%The _beginthread Function%@AE@%%@EH@%%@NL@%
  17490. %@NL@%
  17491. %@AU@% All threads in a process  can execute concurrently.%@AE@%  %@NL@%
  17492. %@NL@%
  17493. The %@AB@%_beginthread%@AE@% function creates a new thread. A thread shares the code and
  17494. data segments of a process with other threads in the process but has its own
  17495. unique register values, stack space, and current instruction address. The
  17496. system gives CPU time to each thread, so that all threads in a process can
  17497. execute concurrently. You can find a complete description of %@AB@%_beginthread%@AE@%
  17498. and its arguments in on-line help.%@CR:C6A00150006 @%%@CR:C6A00150007 @%  %@NL@%
  17499. %@NL@%
  17500. The %@AB@%_beginthread%@AE@% function is similar to the %@AB@%DosCreateThread%@AE@% function in the
  17501. OS/2 API with these differences:  %@NL@%
  17502. %@NL@%
  17503. %@NL@%
  17504.   ■   The %@AB@%_beginthread%@AE@% function lets you pass arguments to the thread.%@NL@%
  17505. %@NL@%
  17506.   ■   The stack address points to the bottom of the stack. It is the address
  17507.       of the start of an array or of the start of a block of dynamically
  17508.       allocated memory. When you use the %@AB@%DosCreateThread%@AE@% call, the stack
  17509.       address points to the top of the stack.%@NL@%
  17510. %@NL@%
  17511.   ■   If you specify %@AB@%NULL%@AE@% for the stack address, %@AB@%_beginthread%@AE@% manages
  17512.       allocation and deallocation of the thread stack for you. This option
  17513.       is advantageous because it is difficult for your program to determine
  17514.       when a thread has terminated, so you cannot know when to deallocate
  17515.       the thread stack. However, %@AB@%_beginthread%@AE@% maintains enough information
  17516.       to know when a thread has terminated and deallocates the thread's
  17517.       stack the next time its thread ID is used.%@NL@%
  17518. %@NL@%
  17519. %@NL@%
  17520. The %@AB@%_beginthread%@AE@% function returns the thread ID number of the new thread if
  17521. successful or -1 if there was an error. Errors include specifying an
  17522. odd-address stack or an odd- or zero-length stack (which is different than
  17523. passing %@AB@%NULL%@AE@% for the stack address) or trying to create too many threads.
  17524. The multithread library, LLIBCMT.LIB, supports the maximum number of threads
  17525. allowed by OS/2.  %@NL@%
  17526. %@NL@%
  17527. %@NL@%
  17528. %@4@%%@AB@%The _endthread Function%@AE@%%@EH@%%@NL@%
  17529. %@NL@%
  17530. The %@AB@%_endthread%@AE@% function terminates a thread created by %@AB@%_beginthread%@AE@%. Threads
  17531. terminate automatically when they complete. The %@AB@%_endthread%@AE@% function is
  17532. useful for conditional termination from within a thread. A thread dedicated
  17533. to communications processing, for example, can quit if it is unable to get
  17534. control of the communications port. You can find a complete description of
  17535. %@AB@%_endthread%@AE@% in on-line help.  %@NL@%
  17536. %@NL@%
  17537. %@NL@%
  17538. %@2@%%@CR:C6A00150008 @%%@AB@%15.2  Sample Multithread C Program%@AE@%%@EH@%%@NL@%
  17539. %@NL@%
  17540. BOUNCE.C is a sample multithread program that creates a new thread each time
  17541. the letter `a' or `A' is entered at the keyboard. Each thread bounces a
  17542. "happy face" of a different color around the screen. Up to 32 threads can be
  17543. created. The program's normal termination occurs when `q' or `Q' is entered.
  17544. It will also terminate if it receives the CTRL+C or CTRL+BREAK signals. See
  17545. Section 15.4, "Compiling and Linking," for details on compiling and linking
  17546. BOUNCE.C.  %@NL@%
  17547. %@NL@%
  17548. %@AS@%  /*  Bounce - Creates a new thread each time the letter 'a'is typed.
  17549. %@AS@%   *  Each thread bounces a happy face of a different color around the
  17550. %@AS@%screen.
  17551. %@AS@%   *  All threads are terminated when the letter 'q' is entered or when
  17552. %@AS@%   *  the CTRL+C/CTRL+BREAK signals are received.
  17553. %@AS@%   *
  17554. %@AS@%   *  This program requires the multithread library. For example, compile
  17555. %@AS@%   *  with the following command line:
  17556. %@AS@%   *      CL /MT BOUNCE.C
  17557. %@AS@%   */
  17558. %@AS@%  
  17559. %@AS@%  #define INCL_NOCOMMON                     /* Use only what we need */
  17560. %@AS@%  #define INCL_NOPM                         /* Don't need PM */
  17561. %@AS@%  #define INCL_DOSPROCESS                   /* DosBeep and DosSleep */
  17562. %@AS@%  #define INCL_DOSSEMAPHORES                /* OS/2 semaphore functions */
  17563. %@AS@%  #define INCL_DOSSIGNALS                   /* OS/2 signal functions */
  17564. %@AS@%  #define INCL_VIO
  17565. %@AS@%  #define INCL_KBD
  17566. %@AS@%  #include <os2.h>
  17567. %@AS@%  #include <stdlib.h>
  17568. %@AS@%  #include <string.h>
  17569. %@AS@%  #include <stdio.h>
  17570. %@AS@%  #include <process.h>
  17571. %@AS@%  
  17572. %@AS@%  #define STACK_SIZE   4096
  17573. %@AS@%  #define MAX_THREADS  32
  17574. %@AS@%  
  17575. %@AS@%  void main( void );                          /* Thread 1: main */
  17576. %@AS@%  void KbdThread( void );                     /* Thread 2: keyboard input */
  17577. %@AS@%  void BounceProc( char * MyID );             /* Threads 3 to n: display */
  17578. %@AS@%  void VioClrScr( void );                     /* Screen clear */
  17579. %@AS@%  void ShutDown( void );                      /* Program shutdown */
  17580. %@AS@%  void VioWrtCStr( char *pchString,           /* Write string to display */
  17581. %@AS@%                   unsigned usRow, unsigned usColumn );
  17582. %@AS@%  void pascal far SigHandler( unsigned SigArg,/* Signal handler */
  17583. %@AS@%                              unsigned SigNum );
  17584. %@AS@%                                              /* Screen clear macro */
  17585. %@AS@%  #define VioClrScr() VioScrollDn( 0, 0, 50, 80, 50, BlankCell, 0 )%@AE@%%@NL@%
  17586. %@NL@%
  17587. %@AS@%  struct tagCoords                            /* Display coordinates */
  17588. %@AS@%  {
  17589. %@AS@%      int xLoc;
  17590. %@AS@%      int yLoc;
  17591. %@AS@%      int xInc;
  17592. %@AS@%      int yInc;
  17593. %@AS@%  };
  17594. %@AS@%  
  17595. %@AS@%  unsigned long  RunFlag = 0;                 /* "Keep Running" semaphore */
  17596. %@AS@%  unsigned long  ScreenLock = 0;              /* Screen update semaphore  */
  17597. %@AS@%  
  17598. %@AS@%  char BlankCell[2] = { 0x20, 0x07 };
  17599. %@AS@%  VIOMODEINFO vmi = { sizeof( VIOMODEINFO ) };/* Mode information */
  17600. %@AS@%  
  17601. %@AS@%  PFNSIGHANDLER PrevHandler;                  /* for SetSigHandler call */
  17602. %@AS@%  unsigned int  PrevAction;                   /* for SetSigHandler call */
  17603. %@AS@%  
  17604. %@AS@%  void main()                                 /* Thread One */
  17605. %@AS@%  {
  17606. %@AS@%      /* Get display screen's text row and column sizes & clear the
  17607. %@AS@%screen.*/
  17608. %@AS@%      VioGetMode( &vmi, 0 );
  17609. %@AS@%      VioClrScr();
  17610. %@AS@%      VioWrtCStr( "Threads running: 00.  Press 'a' to start another thread",
  17611. %@AS@%                  vmi.row - 1, 0 );
  17612. %@AS@%  
  17613. %@AS@%      /* Set the "we are running" semaphore. */
  17614. %@AS@%      DosSemSet( &RunFlag );
  17615. %@AS@%  
  17616. %@AS@%      /* Start keyboard thread. Let _beginthread allocate memory
  17617. %@AS@%       *  for the thread's stack.
  17618. %@AS@%       */
  17619. %@AS@%      _beginthread( KbdThread, NULL, STACK_SIZE, NULL );
  17620. %@AS@%  
  17621. %@AS@%      /* Install signal handler for CTRL+BREAK & CRTL+C. */
  17622. %@AS@%      DosSetSigHandler( (PFNSIGHANDLER)SigHandler, &PrevHandler,
  17623. %@AS@%&PrevAction,
  17624. %@AS@%                         SIGA_ACCEPT, SIG_CTRLC );
  17625. %@AS@%  
  17626. %@AS@%      /* Wait for "running" semaphore to clear (from signal or 'q' key). */
  17627. %@AS@%      DosSemWait( &RunFlag, SEM_INDEFINITE_WAIT );
  17628. %@AS@%  
  17629. %@AS@%      _endthread();             /* Kill all threads */
  17630. %@AS@%  }%@AE@%%@NL@%
  17631. %@NL@%
  17632. %@AS@%  void pascal far SigHandler( unsigned int SigArg, unsigned int SigNum )
  17633. %@AS@%  {
  17634. %@AS@%      static char BreakMsg[] = "Signal Termination";
  17635. %@AS@%  
  17636. %@AS@%      ShutDown();
  17637. %@AS@%      VioWrtCStr( BreakMsg, vmi.row - 1, 0 );
  17638. %@AS@%      /* Restore original signal handler for CTRL+BREAK & CRTL+C. */
  17639. %@AS@%      DosSetSigHandler( (PFNSIGHANDLER)PrevHandler, &PrevHandler,
  17640. %@AS@%&PrevAction,
  17641. %@AS@%                         PrevAction, SIG_CTRLC );
  17642. %@AS@%  }
  17643. %@AS@%  void ShutDown( void )                       /* Clean up display when done
  17644. %@AS@%*/
  17645. %@AS@%  {
  17646. %@AS@%      /* Lock out screen updates from BounceProc & clear "running" semaphore
  17647. %@AS@%*/
  17648. %@AS@%      DosSemWait( &ScreenLock, SEM_INDEFINITE_WAIT );
  17649. %@AS@%      DosSemSet( &ScreenLock );
  17650. %@AS@%      VioClrScr();
  17651. %@AS@%      DosSemClear( &RunFlag );
  17652. %@AS@%  }
  17653. %@AS@%  
  17654. %@AS@%  void KbdThread( void )                          /* Thread Two: keyboard */
  17655. %@AS@%  {
  17656. %@AS@%      KBDKEYINFO  KeyInfo;                        /* for KbdCharIn call */
  17657. %@AS@%      char        ThreadNr = 0;
  17658. %@AS@%      char        NThreadMsg[4];
  17659. %@AS@%  
  17660. %@AS@%      do
  17661. %@AS@%      {
  17662. %@AS@%          /* Block this thread by waiting for keyboard input. */
  17663. %@AS@%  
  17664. %@AS@%          KbdCharIn( &KeyInfo, IO_WAIT, 0 );
  17665. %@AS@%          if( tolower( KeyInfo.chChar ) == 'a' && ThreadNr < MAX_THREADS)
  17666. %@AS@%          {
  17667. %@AS@%              ThreadNr++;
  17668. %@AS@%              _beginthread( BounceProc, NULL, STACK_SIZE, &ThreadNr );
  17669. %@AS@%              VioWrtCharStr( NThreadMsg, sprintf( NThreadMsg, "%02d",
  17670. %@AS@%ThreadNr ),
  17671. %@AS@%                             vmi.row - 1, 17, 0 );
  17672. %@AS@%          }
  17673. %@AS@%      } while( tolower( KeyInfo.chChar ) != 'q' );
  17674. %@AS@%  
  17675. %@AS@%      ShutDown();
  17676. %@AS@%  }
  17677. %@AS@%  
  17678. %@AS@%  /* getrandom returns a random number between min and max, which must be in
  17679. %@AS@%   * integer range.
  17680. %@AS@%   */
  17681. %@AS@%  #define getrandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) +
  17682. %@AS@%(min))%@AE@%%@NL@%
  17683. %@NL@%
  17684. %@AS@%  void BounceProc( char * MyID )                  /* Threads Three to n */
  17685. %@AS@%  {
  17686. %@AS@%      int       xOld, yOld;
  17687. %@AS@%      char      MyCell[2];
  17688. %@AS@%      char      CurrentCell[2];
  17689. %@AS@%      int       CellLen = 2;
  17690. %@AS@%      struct tagCoords Coords;%@AE@%%@NL@%
  17691. %@NL@%
  17692. %@AS@%   /* Generate update increments and initial display coordinates. */
  17693. %@AS@%      srand( (unsigned) *MyID * 3 );
  17694. %@AS@%      Coords.xLoc = getrandom( 0, vmi.col - 1 );
  17695. %@AS@%      Coords.yLoc = getrandom( 0, vmi.row - 1 );
  17696. %@AS@%      Coords.xInc = getrandom( -3, 3 );
  17697. %@AS@%      Coords.yInc = getrandom( -3, 3 );
  17698. %@AS@%  
  17699. %@AS@%      /* Set up "happy face" & generate color attribute from thread
  17700. %@AS@%number.*/
  17701. %@AS@%      if( *MyID > 16)
  17702. %@AS@%          MyCell[0] = 0x01;          /* outline face */
  17703. %@AS@%      else
  17704. %@AS@%          MyCell[0] = 0x02;          /* solid face */
  17705. %@AS@%      MyCell[1] =  *MyID & 0x0F;     /* force black background */
  17706. %@AS@%  
  17707. %@AS@%      for( ;; )
  17708. %@AS@%      {
  17709. %@AS@%          /* Wait for display to be available, then lock it. */
  17710. %@AS@%          DosSemWait( &ScreenLock, SEM_INDEFINITE_WAIT );
  17711. %@AS@%          DosSemSet( &ScreenLock );
  17712. %@AS@%  
  17713. %@AS@%          /* If we still occupy the old screen position, blank it out. */
  17714. %@AS@%          VioReadCellStr( CurrentCell, &CellLen, yOld, xOld, 0 );
  17715. %@AS@%          if ( CurrentCell[0] == MyCell[0] && CurrentCell[1] == MyCell[1] )
  17716. %@AS@%              VioWrtCellStr( BlankCell, CellLen, yOld, xOld, 0 );
  17717. %@AS@%  
  17718. %@AS@%          /* Draw new face, then clear screen lock */
  17719. %@AS@%          VioWrtCellStr( MyCell, CellLen, Coords.yLoc, Coords.xLoc, 0 );
  17720. %@AS@%          DosSemClear( &ScreenLock );
  17721. %@AS@%  
  17722. %@AS@%          /* Increment the coordinates for next placement of the block. */
  17723. %@AS@%          xOld = Coords.xLoc;
  17724. %@AS@%          yOld = Coords.yLoc;
  17725. %@AS@%          Coords.xLoc += Coords.xInc;
  17726. %@AS@%          Coords.yLoc += Coords.yInc;
  17727. %@AS@%  
  17728. %@AS@%   %@AE@%%@NL@%
  17729. %@NL@%
  17730. %@AS@%         /* If we are about to go off the screen, reverse direction */
  17731. %@AS@%          if( Coords.xLoc < 0 || Coords.xLoc >= vmi.col )
  17732. %@AS@%          {
  17733. %@AS@%              Coords.xInc = -Coords.xInc;
  17734. %@AS@%              DosBeep( 400, 50 );
  17735. %@AS@%          }
  17736. %@AS@%          if( Coords.yLoc < 0 || Coords.yLoc >= vmi.row )
  17737. %@AS@%          {
  17738. %@AS@%              Coords.yInc = -Coords.yInc;
  17739. %@AS@%              DosBeep( 600, 50 );
  17740. %@AS@%          }
  17741. %@AS@%  
  17742. %@AS@%          /* Sleep to slow down screen update rate */
  17743. %@AS@%          DosSleep( 75L );
  17744. %@AS@%      }
  17745. %@AS@%  }
  17746. %@AS@%  
  17747. %@AS@%  void VioWrtCStr( char *pchString, unsigned usRow, unsigned usColumn )
  17748. %@AS@%  {
  17749. %@AS@%      VioWrtCharStr( pchString, strlen( pchString ), usRow, usColumn, 0 );
  17750. %@AS@%  }%@AE@%%@NL@%
  17751. %@NL@%
  17752. %@NL@%
  17753. %@2@%%@CR:C6A00150009 @%%@AB@%15.3  Writing a Multithread Program%@AE@%%@EH@%%@NL@%
  17754. %@NL@%
  17755. When you write a program with multiple threads, you must coordinate their
  17756. behavior and use of the program's resources. You must also make sure that
  17757. each thread receives its own stack.  %@NL@%
  17758. %@NL@%
  17759. %@NL@%
  17760. %@4@%%@AB@%Sharing Common Resources%@AE@%%@EH@%%@NL@%
  17761. %@NL@%
  17762. Each thread has its own stack and its own copy of the CPU registers. Other
  17763. resources, such as files, static data, and heap memory, are shared by all
  17764. threads in the process. Threads using these common resources must coordinate
  17765. their work. OS/2 provides semaphores and the %@AB@%DosEnterCritSec%@AE@% and
  17766. %@AB@%DosExitCritSec%@AE@% system services for synchronizing resources.  %@NL@%
  17767. %@NL@%
  17768. %@AU@% Your program must provide  for resource conflicts.%@AE@%  %@NL@%
  17769. %@NL@%
  17770. When multiple threads are accessing static data, your program must provide
  17771. for possible resource conflicts. Consider a program where one thread updates
  17772. a static data structure containing %@AI@%x%@AE@%,%@AI@%y%@AE@% coordinates for items to be displayed
  17773. by another thread. If the update thread alters the %@AI@%x%@AE@% coordinate and is
  17774. preempted before it can change the %@AI@%y%@AE@% coordinate, the display thread may be
  17775. scheduled before the %@AI@%y%@AE@% coordinate is updated. The item would be displayed at
  17776. the wrong location. You can avoid this type of problem by using semaphores
  17777. to control access to the structure.  %@NL@%
  17778. %@NL@%
  17779. Using semaphores is a way of communicating among threads or processes that
  17780. are executing asynchronously of one another. This communication is usually
  17781. used to coordinate the activities of multiple threads or processes,
  17782. typically by controlling access to a shared resource by "locking" and
  17783. "unlocking" the resource. To solve the %@AI@%x,y%@AE@% coordinate update problem
  17784. described above, the update thread would set a semaphore indicating that the
  17785. data structure is in use before performing the update. It would then clear
  17786. the semaphore when both coordinates had been processed. The display thread
  17787. must wait for the semaphore to be clear before updating the display. This
  17788. process of waiting for a semaphore is often called "blocking" on a semaphore
  17789. because the process is blocked and cannot continue until the semaphore
  17790. clears.  %@NL@%
  17791. %@NL@%
  17792. %@AU@% RAM semaphores are faster  than system semaphores.%@AE@%  %@NL@%
  17793. %@NL@%
  17794. OS/2 supports two types of semaphores: system and RAM semaphores. You must
  17795. use a system semaphore if more than one process needs to access the
  17796. semaphore. You can use the much faster RAM semaphores if their use is
  17797. confined to the threads within a process.  %@NL@%
  17798. %@NL@%
  17799. The BOUNCE.C program in Section 15.2 uses a RAM semaphore named %@AS@% ScreenLock %@AE@%
  17800. to coordinate screen updates. Each time one of the display threads is ready
  17801. to write to the screen, it calls %@AB@%DosSemWait%@AE@% with a pointer to %@AS@% ScreenLock
  17802. %@AS@%%@AE@%and constant %@AB@%SEM_INDEFINITE_WAIT%@AE@% to indicate that the %@AB@%DosSemWait %@AE@%call should
  17803. block on the semaphore and not time out. If the %@AS@%ScreenLock %@AE@%semaphore is
  17804. clear, the wait function returns immediately. Otherwise, the thread blocks
  17805. until the semaphore clears. When the thread receives control again, it calls
  17806. %@AB@%DosSemSet%@AE@% to set the %@AS@%ScreenLock %@AE@%semaphore so other threads cannot interfere
  17807. with the display. When the thread completes the display update, it releases
  17808. the semaphore by calling %@AB@%DosSemClear%@AE@%.%@AS@%  %@AE@%%@NL@%
  17809. %@NL@%
  17810. The %@AS@% ShutDown %@AE@% routine in BOUNCE.C is called from both the keyboard thread
  17811. and the signal handler. The routine uses the %@AS@% ScreenLock %@AE@% semaphore to make
  17812. sure other threads do not write to the screen after the screen has been
  17813. cleared.  %@NL@%
  17814. %@NL@%
  17815. Screen displays and static data are only two of the resources requiring
  17816. careful management. For example, your program may have multiple threads
  17817. accessing the same file. Since another thread may have moved the file
  17818. pointer, each thread must reset the file pointer before reading or writing.
  17819. In addition, each thread must make sure that it is not preempted between the
  17820. time it positions the pointer and the time it accesses the file. These
  17821. threads should use a semaphore to coordinate access to the file by
  17822. bracketing each file access with %@AB@%DosSemRequest%@AE@% and %@AB@%DosSemClear%@AE@% calls. The
  17823. following code fragment illustrates this technique:  %@NL@%
  17824. %@NL@%
  17825. %@AS@%  HSEM    hsemIOSem;
  17826. %@AS@%  
  17827. %@AS@%  DosSemRequest( hsemIOSem, SEM_INDEFINITE_WAIT );
  17828. %@AS@%  fseek( fp, desired_position, 0L );
  17829. %@AS@%  fwrite( data, sizeof( data ), 1, fp );
  17830. %@AS@%  DosSemClear( hsemIOSem );%@AE@%%@NL@%
  17831. %@NL@%
  17832. %@NL@%
  17833. %@4@%%@AB@%Thread Stacks%@AE@%%@EH@%%@NL@%
  17834. %@NL@%
  17835. %@AU@% Stack checking is performed for each thread.%@AE@%  %@NL@%
  17836. %@NL@%
  17837. All of an application's default stack space is allocated to the first thread
  17838. of execution, which is known as thread 1. As a result, you must allocate
  17839. memory to provide a separate stack for each additional thread your program
  17840. needs. You must do this before creating the thread. Stack checking, if
  17841. enabled, is performed for each thread. The keyboard thread in BOUNCE.C calls
  17842. the %@AB@%malloc%@AE@% function each time the user wants to start a new display thread.
  17843. If the allocation is successful, the %@AB@%_beginthread%@AE@% function is called. The
  17844. first argument in the %@AB@%_beginthread%@AE@% call is a pointer to the %@AB@%BounceProc%@AE@%
  17845. function, which will execute the threads. The last argument is an ID number
  17846. that is passed to %@AB@%BounceProc%@AE@%. %@AB@%BounceProc%@AE@% uses the ID number to seed the
  17847. random number generator and to select the thread's color attribute and
  17848. display character.  %@NL@%
  17849. %@NL@%
  17850. Threads that make calls to the C run-time library or to the OS/2 API must
  17851. allow sufficient stack space for the library and API functions they call.
  17852. The C %@AB@%printf%@AE@% function requires more than 500 bytes of stack space, and you
  17853. should have 2K of stack space available when calling OS/2 API routines. To
  17854. be safe, allocate at least 4K for each thread's stack.  %@NL@%
  17855. %@NL@%
  17856. %@AU@% Use as little static  data as possible.%@AE@%  %@NL@%
  17857. %@NL@%
  17858. Since each thread has its own stack, you can avoid potential collisions over
  17859. data items by using as little static data as possible. Design your program
  17860. to use automatic stack variables for all data that can be private to a
  17861. thread. The only global variables in the BOUNCE.C program are either RAM
  17862. semaphores or variables that never change once they are initialized.  %@NL@%
  17863. %@NL@%
  17864. %@NL@%
  17865. %@4@%%@AB@%Signal Handling%@AE@%%@EH@%%@NL@%
  17866. %@NL@%
  17867. Signals are events that interrupt the normal flow of your program's
  17868. execution. They are similar to hardware interrupts, but they come from the
  17869. operating system or other programs and occur asynchronously. If you do not
  17870. provide your own routines, OS/2 will take the default action for each
  17871. signal, such as cancelling your program when the user enters CTRL+BREAK. You
  17872. can install your own signal handler with the OS/2 API function
  17873. %@AB@%DosSetSigHandler%@AE@%.  %@NL@%
  17874. %@NL@%
  17875. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17876. %@AU@%WARNING%@AE@%%@NL@%
  17877. %@NL@%
  17878. The C run-time function signal is not supported in the multithread library
  17879. LLIBCMT.LIB.%@NL@%
  17880. ────────────────────────────────────────────────────────────────────────────%@NL@%
  17881. %@NL@%
  17882. When a signal occurs, OS/2 always suspends thread 1 and gives control to the
  17883. signal handler, if installed. As a result, thread 1 must not be executing C
  17884. run-time library code when the signal handler gets control or a potential
  17885. deadlock condition can occur. In addition, the signal handler must not call
  17886. C run-time library functions. Consider the following sequence of events:  %@NL@%
  17887. %@NL@%
  17888. %@NL@%
  17889.   1.  Thread 2 is executing %@AB@%printf%@AE@% when the user interrupts it by pressing
  17890.       CTRL+C. The program has designated a CTRL+C signal handler, so OS/2
  17891.       immediately transfers control to the signal handler in thread 1.%@NL@%
  17892. %@NL@%
  17893.   2.  The signal handler in thread 1 tries to execute the statement: 
  17894. %@NL@%
  17895. %@AS@%      printf( "^C: Do you want to quit?" );%@AE@%%@NL@%
  17896. %@NL@%
  17897. %@NL@%
  17898.   3.  The %@AB@%printf%@AE@% call in thread 2 has already locked output to the console,
  17899.       so thread 1's %@AB@%printf%@AE@% must wait for release of that lock.%@NL@%
  17900. %@NL@%
  17901.   4.  The thread 2 %@AB@%printf%@AE@% function never regains control because the signal
  17902.       handler must complete before other processing can continue. As a
  17903.       result, it is never able to release the lock on console output.%@NL@%
  17904. %@NL@%
  17905. %@NL@%
  17906. If a situation like this happens, the program will wait indefinitely for
  17907. resolution of the two mutually exclusive conditions.  %@NL@%
  17908. %@NL@%
  17909. A multithread C program can process signals if it adheres to the following
  17910. restrictions:  %@NL@%
  17911. %@NL@%
  17912. %@NL@%
  17913.   ■   Thread 1 must be dedicated to signal handling and must not call the C
  17914.       run-time library once it identifies the signal handler to OS/2 using
  17915.       the API function %@AB@%DosSetSigHandler%@AE@%. When the signal handler gets
  17916.       control, it should set a semaphore or flag so other threads in the
  17917.       program can determine that the signal has occurred and is being
  17918.       processed.%@NL@%
  17919. %@NL@%
  17920.   ■   The other threads in the process must check the status of semaphores
  17921.       set by thread 1 and respond accordingly. %@NL@%
  17922. %@NL@%
  17923. %@NL@%
  17924. The BOUNCE.C sample program waits until thread 2, the keyboard handler,
  17925. starts before installing the signal handler. It then dedicates thread 1 to
  17926. signal handling by having the thread wait for a semaphore. Thread 1 blocks
  17927. until either the keyboard thread or the signal handler clears the semaphore.
  17928. It then calls %@AB@%_endthread%@AE@% to terminate the process, including all the other
  17929. threads.  %@NL@%
  17930. %@NL@%
  17931. %@NL@%
  17932. %@2@%%@CR:C6A00150010 @%%@AB@%15.4  Compiling and Linking%@AE@%%@EH@%%@NL@%
  17933. %@NL@%
  17934. The steps for compiling and linking the multithread program BOUNCE.C are
  17935. given below:  %@NL@%
  17936. %@NL@%
  17937. %@NL@%
  17938.   1.  Ensure that the files LLIBCMT.LIB and OS2.LIB are in the directory
  17939.       specified in your LIB environment variable.%@NL@%
  17940. %@NL@%
  17941. %@STUB@%      The file LLIBCMT.LIB takes the place of the regular C run-time library
  17942.       files. The file OS2.LIB provides support for OS/2 system calls made in
  17943.       the program, such as %@AB@%KbdCharIn%@AE@%.%@NL@%
  17944. %@NL@%
  17945.   2.  Compile and link the program with the CL command-line option /MT.%@NL@%
  17946. %@NL@%
  17947. %@STUB@%      The /Lp option instructs the compiler to create a protected-mode
  17948.       application. The /MT option implies the large memory model with a
  17949.       separate stack segment (/ALw). The multithread library functions have
  17950.       their own data segment but use the caller's stack. This option also
  17951.       sets the library search record to LLIBCMT.LIB and sets the %@AB@%MT%@AE@% symbolic
  17952.       constant for the multithread versions of the include files. The /link
  17953.       GRTEXTP option instructs the linker to search GRTEXTP.LIB, the
  17954.       character-graphics library for protected mode.%@NL@%
  17955. %@NL@%
  17956. %@STUB@%      To compile and link in a single step, use this CL command line:%@NL@%
  17957. %@NL@%
  17958. %@AS@%      CL /Lp /MT BOUNCE.C /link grtextp%@AE@%%@NL@%
  17959. %@NL@%
  17960. %@STUB@%      For separate compile and link steps, you invoke the compiler and the
  17961.       linker with this code:%@NL@%
  17962. %@NL@%
  17963. %@AS@%      CL /c /Lp /MT BOUNCE.C
  17964. %@AS@%      LINK BOUNCE;%@AE@%%@NL@%
  17965. %@NL@%
  17966.   3.  If you choose not to use the /MT option, you must take these steps:%@NL@%
  17967. %@NL@%
  17968. %@NL@%
  17969. %@NL@%
  17970.   ■   Ensure that the special multithread include file support is enabled.
  17971. %@NL@%
  17972.       ■   Use the /Aw option. This is required because the functions in
  17973.           LLIBCMT.LIB have their own data segment but use the caller's
  17974.           stack. The /Aw option specifies a segment setup of SS not equal to
  17975.           DS with DS not reloaded on function entry.%@NL@%
  17976. %@NL@%
  17977.       ■   Make sure that only far pointers are passed to library functions.%@NL@%
  17978. %@NL@%
  17979.       ■   Make sure that all variables are either passed by value or cast to
  17980.           a far address (the large memory model).%@NL@%
  17981. %@NL@%
  17982.       ■   Specify the multithread library and suppress default library
  17983.           selection.%@NL@%
  17984. %@NL@%
  17985. %@STUB@%      The multithread include files are used when you define the symbolic
  17986.       constant %@AB@%MT%@AE@%. You can do this with the CL command line option /D MT or
  17987.       within the C source file before any include statements, as shown
  17988.       below:%@NL@%
  17989. %@NL@%
  17990. %@AS@%      #define MT
  17991. %@AS@%      #include <stdlib.h>%@AE@%%@NL@%
  17992. %@NL@%
  17993. %@STUB@%      To compile and link in a single step with the default libraries
  17994.       suppressed, this is the complete CL command line:%@NL@%
  17995. %@NL@%
  17996. %@AS@%      CL /Lp /ALw /Zl /D MT BOUNCE.C /link LLIBCMT+OS2%@AE@%%@NL@%
  17997. %@NL@%
  17998. %@STUB@%      To perform a two-step compile and link with the default libraries
  17999.       suppressed in the link step, use these commands:%@NL@%
  18000. %@NL@%
  18001. %@AS@%      CL /c /Lp /ALw /D MT BOUNCE.C
  18002. %@AS@%      LINK /NOD BOUNCE,,,LLIBCMT+OS2;%@AE@%%@NL@%
  18003. %@NL@%
  18004.       1.  Run the program under OS/2.%@NL@%
  18005. %@NL@%
  18006. %@NL@%
  18007. %@NL@%
  18008. %@NL@%
  18009. %@2@%%@CR:C6A00150011 @%%@AB@%15.5  Avoiding Problem Areas%@AE@%%@EH@%%@NL@%
  18010. %@NL@%
  18011. There are several problems you can encounter in creating, linking, or
  18012. executing a multithread C program. Some of the more common ones are
  18013. described here.  %@NL@%
  18014. %@NL@%
  18015. %@AB@%Problem%@AE@%                           %@AB@%Probable Cause%@AE@%
  18016. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18017. LINK searches for mLIBC%@AI@% f%@AE@%.LIB.    If you omit the /NOD option from the 
  18018.                                   LINK command, LINK searches for the 
  18019.                                   default library. The
  18020.                                   default library should not be used with 
  18021.                                   multithread programs. The /NOD option 
  18022.                                   tells the computer not to search the 
  18023.                                   default libraries. This problem can also
  18024.                                   be avoided by compiling with the /Zl 
  18025.                                   option, which suppresses default library
  18026.                                   search records in the object files.
  18027.  
  18028. You get error SYS1943. A program  Many OS/2 programming errors cause 
  18029. caused a protection               protection violations. A common cause of
  18030. violation.                        protection violations is the indirect 
  18031.                                   assignment of data to null pointers. 
  18032.                                   This results in your program trying to 
  18033.                                   access memory that does not "belong" to 
  18034.                                   it, so a protection violation is issued.
  18035.                                   Protection violations also occur if your
  18036.                                   program gets a memory buffer from the 
  18037.                                   operating system and then tries to read 
  18038.                                   or write past the end of the 
  18039.  
  18040.                                   buffer. Another cause of this error is 
  18041.                                   failing to specify the condition "SS is 
  18042.                                   not equal to DS" in the CL command 
  18043.                                   invocation. Specify the correct 
  18044.                                   conditions with the /ALw memory model 
  18045.                                   option.
  18046.  
  18047.                                   An easy way to detect the cause of a 
  18048.                                   protection violation is to compile your 
  18049.                                   program with CodeView information, then 
  18050.                                   run it in CodeView. When the protection 
  18051.                                   fault occurs, OS/2 will transfer control
  18052.                                   to CodeView, and the cursor will be 
  18053.                                   positioned on the line that caused the 
  18054.                                   problem. See Chapter 9, "Debugging C 
  18055.                                   Programs with CodeView," for more 
  18056.                                   information about the CodeView debugger.
  18057.  
  18058. Your program generates numerous   If you attempt to compile and link a 
  18059. compile and link errors.          multithread
  18060.                                   program without defining the symbolic 
  18061.                                   constant%@AB@% MT%@AE@%, many of the definitions 
  18062.                                   required for the multithread library 
  18063.                                   will be missing. Define %@AB@%MT%@AE@% on the CL 
  18064.                                   command line with /MT or /D MT, or use %@AS@% %@AE@%
  18065.                                   %@AS@%#define MT %@AE@%in your program.
  18066.  
  18067. You can eliminate many potential problems by setting the compiler's warning
  18068. level to one of its highest values and heeding the warning messages. By
  18069. using the /W3 or /W4 warning level options, you can detect unintentional
  18070. data conversions, missing function prototypes, and use of non-ANSI features.
  18071. %@NL@%
  18072. %@NL@%
  18073. %@NL@%
  18074. %@2@%%@CR:C6A00150012 @%%@AB@%15.6  Using the Protected-Mode CodeView Debugger%@AE@%%@EH@%%@NL@%
  18075. %@NL@%
  18076. The protected-mode version of CodeView (CVP) has special commands for
  18077. debugging multiple processes and threads. It adds Thread and Process items
  18078. to the standard Run Menu. Your CONFIG.SYS file must specify IOPL=YES for
  18079. protected-mode CodeView to run.%@CR:C6A00150013 @%%@CR:C6A00150014 @%%@CR:C6A00150015 @%  %@NL@%
  18080. %@NL@%
  18081. To enable multiple process debugging, invoke CodeView with the /O
  18082. (offspring) option. Selecting the Process item from the Run Menu brings up a
  18083. list box of child processes associated with the parent process. You choose
  18084. the process to be debugged by selecting it with the list box. The Process
  18085. item will be grey (unselectable) if you did not specify the /O option. The
  18086. /O option applies only to debugging multiple processes. You do not need to
  18087. use it to debug multiple threads.  %@NL@%
  18088. %@NL@%
  18089. Selecting the Thread item from the Run Menu produces a list box showing the
  18090. status of each thread associated with the current process. You can use the
  18091. list box to designate a different current thread or to change a thread's
  18092. status. There are equivalent keyboard commands for each option.  %@NL@%
  18093. %@NL@%
  18094. %@NL@%
  18095. %@3@%%@CR:C6A00150016 @%%@AB@%15.6.1  Compiling with the /Zi Option%@AE@%%@EH@%%@NL@%
  18096. %@NL@%
  18097. The compiler option /Zi causes the compiler to include symbolic information
  18098. and line numbers in the object file for debugging with CodeView. If you run
  18099. LINK in a separate step, you must invoke it with the /CODEVIEW option, which
  18100. can be abbreviated as /CO. To compile and link the sample program BOUNCE.C
  18101. in a single step, enter this code:  %@NL@%
  18102. %@NL@%
  18103. %@AS@%  CL /MT /Zi BOUNCE.C%@AE@%%@NL@%
  18104. %@NL@%
  18105. The following commands are for a two-step compile and link:  %@NL@%
  18106. %@NL@%
  18107. %@AS@%  CL /c /MT /Zi BOUNCE.C
  18108. %@AS@%  
  18109. %@AS@%  link /CO BOUNCE;%@AE@%%@NL@%
  18110. %@NL@%
  18111. %@NL@%
  18112. %@3@%%@CR:C6A00150017 @%%@AB@%15.6.2  Prompt for Thread Number%@AE@%%@EH@%%@NL@%
  18113. %@NL@%
  18114. When you debug a protected-mode program with CodeView, the command prompt is
  18115. preceded by a three-digit number indicating the current thread. Thread 1 is
  18116. always the current thread when you start a program. The prompt appears as  %@NL@%
  18117. %@NL@%
  18118. %@AS@%  001>%@AE@%%@NL@%
  18119. %@NL@%
  18120. %@NL@%
  18121. %@3@%%@CR:C6A00150018 @%%@AB@%15.6.3  Thread Commands%@AE@%%@EH@%%@NL@%
  18122. %@NL@%
  18123. Protected-mode CodeView (CVP) has special commands to control the execution
  18124. of threads. The CodeView Thread commands are accessed using the Thread
  18125. command from the Run menu. Dialog commands for thread control start with the
  18126. tilde character (%@AB@%~%@AE@%). Thread commands specify which thread(s) the command
  18127. applies to, followed by the command. The syntax of the dialog version of the
  18128. Thread command is  %@NL@%
  18129. %@NL@%
  18130. %@AB@%~%@AE@%«%@AI@%specifier%@AE@%«%@AI@%command%@AE@%»»  %@NL@%
  18131. %@NL@%
  18132. Entering the tilde character by itself displays the status of all threads.
  18133. Enter the tilde and a specifier to see the status of particular threads.
  18134. Legal values for the specifier field are listed below:  %@NL@%
  18135. %@NL@%
  18136. %@AB@%Specifier%@AE@%                         %@AB@%Function%@AE@%
  18137. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18138. (blank)                           Displays the status of all threads
  18139.  
  18140. #                                 Specifies the last thread that executed
  18141.  
  18142. .                                 Specifies the current thread
  18143.  
  18144. *                                 Specifies all threads
  18145.  
  18146. n                                 Specifies the number of an existing 
  18147.                                   thread
  18148.  
  18149. The optional command field controls the way specified threads are executed.
  18150. If it is omitted, status is displayed, but thread activity is not affected.
  18151. Thread commands are summarized below, followed by examples. For more
  18152. information about command execution and about how other threads in the
  18153. process may be affected, consult on-line help.  %@NL@%
  18154. %@NL@%
  18155. %@AB@%Command%@AE@%                           %@AB@%Function%@AE@%
  18156. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18157. (blank)                           Display status
  18158.  
  18159. %@AB@%BP%@AE@%                                Set a breakpoint (used with the normal 
  18160.                                   Breakpoint Set command syntax)
  18161.  
  18162. %@AB@%E%@AE@%                                 Execute in slow motion
  18163.  
  18164. %@AB@%F%@AE@%                                 Freeze the thread(s)
  18165.  
  18166. %@AB@%G%@AE@%                                 Pass control to a thread
  18167.  
  18168. %@AB@%P%@AE@%                                 Execute a program step
  18169.  
  18170. %@AB@%S%@AE@%                                 Select specified thread as the current 
  18171.                                   thread
  18172.  
  18173. %@AB@%T%@AE@%                                 Trace a thread
  18174.  
  18175. %@AB@%U%@AE@%                                 Unfreeze thread(s)
  18176.  
  18177. %@NL@%
  18178. %@4@%%@AB@%Controlling a Thread Being Debugged%@AE@%%@EH@%%@NL@%
  18179. %@NL@%
  18180. If your program has multiple threads using the same functions, you may want
  18181. to monitor the behavior of one particular thread. The standard Breakpoint
  18182. Set command will affect every thread. The thread Breakpoint Set command lets
  18183. you limit the breakpoint to one or more threads. The sample program BOUNCE.C
  18184. has multiple threads executing the function %@AB@%BounceProc%@AE@%. This function erases
  18185. the symbol at the thread's current screen position, writes it to a new
  18186. location, computes the display coordinates to be used the next time the
  18187. thread receives control, and then sleeps to slow down the rate at which the
  18188. display is updated.  %@NL@%
  18189. %@NL@%
  18190. Since thread-specific breakpoints can only be set for threads that are
  18191. already running, you can set a breakpoint that will be executed after the
  18192. target thread starts. In BOUNCE.C, the source line in thread 2 that tests
  18193. each character received from the keyboard is a good location for such a
  18194. breakpoint (line 113). Since thread 2 is not active when the program begins,
  18195. you must first set a breakpoint in thread 1 after it has started thread 2
  18196. (line 73). The first breakpoint can be set by conventional methods or by
  18197. using the thread breakpoint command:  %@NL@%
  18198. %@NL@%
  18199. %@AS@%  001>~1BP .73%@AE@%%@NL@%
  18200. %@NL@%
  18201. Once you have reached the first breakpoint, you can set the keyboard test
  18202. breakpoint for thread 2:  %@NL@%
  18203. %@NL@%
  18204. %@AS@%  001>~2BP .113%@AE@%%@NL@%
  18205. %@NL@%
  18206. The BOUNCE.C program starts a new thread each time the letter `a' is typed.
  18207. (`A' is also accepted.) Once you have started the desired number of threads,
  18208. you can trigger the thread 2 breakpoint without starting a new thread by
  18209. pressing another key, such as the space bar. When you reach the breakpoint
  18210. in thread 2, you can set breakpoints for the other threads. To set a
  18211. breakpoint in thread 3's %@AB@%BounceProc%@AE@% function immediately after it has
  18212. updated the screen (source line 168), enter this code:  %@NL@%
  18213. %@NL@%
  18214. %@AS@%  001>~3BP .168%@AE@%%@NL@%
  18215. %@NL@%
  18216. When this breakpoint is reached, the CodeView prompt will reflect the
  18217. current thread number:  %@NL@%
  18218. %@NL@%
  18219. %@AS@%  003>%@AE@%%@NL@%
  18220. %@NL@%
  18221. You can then set other breakpoints for the thread, execute it in slow motion
  18222. without any other threads running in the background, or enter other CodeView
  18223. commands, such as Breakpoint Clear.  %@NL@%
  18224. %@NL@%
  18225. %@NL@%
  18226. %@4@%%@AB@%Freezing and Unfreezing Threads%@AE@%%@EH@%%@NL@%
  18227. %@NL@%
  18228. %@AU@% Frozen threads do not execute.%@AE@%  %@NL@%
  18229. %@NL@%
  18230. It can be useful to freeze one or more threads so they don't interfere with
  18231. execution of a thread you are debugging. In the BOUNCE.C program, for
  18232. example, you can monitor the path of a single bouncing ball by freezing all
  18233. but one of the bounce threads. Frozen threads will not be scheduled for
  18234. execution.  %@NL@%
  18235. %@NL@%
  18236. If you have a large number of threads running, you can freeze all of them in
  18237. a single command and then unfreeze the threads you want to monitor. Unfrozen
  18238. threads continue to operate normally and will execute any breakpoints they
  18239. encounter. The following example freezes all threads, enables threads 1 and
  18240. 4, and then checks the status of all threads:  %@NL@%
  18241. %@NL@%
  18242. %@AS@%  001>~*F
  18243. %@AS@%  001>~1U
  18244. %@AS@%  001>~4U
  18245. %@AS@%  001>~%@AE@%%@NL@%
  18246. %@NL@%
  18247. If thread 1 is waiting for a semaphore when the status command is invoked,
  18248. the report shows the following:  %@NL@%
  18249. %@NL@%
  18250. %@AS@%  001 Blocked
  18251. %@AS@%  002 Frozen
  18252. %@AS@%  003 Frozen
  18253. %@AS@%  004 Runnable%@AE@%%@NL@%
  18254. %@NL@%
  18255. %@NL@%
  18256. %@4@%%@AB@%Switching to a Particular Thread%@AE@%%@EH@%%@NL@%
  18257. %@NL@%
  18258. The %@AB@%S%@AE@% (select) and %@AB@%E%@AE@% (execute) variations of the Thread command can be used
  18259. to switch the current thread. However, when another thread causes the
  18260. program to stop by hitting a breakpoint, the debugger will select the thread
  18261. that encountered the breakpoint as the current thread.  %@NL@%
  18262. %@NL@%
  18263. If you include %@AB@%~.S%@AE@% in the breakpoint command, CodeView stops the thread that
  18264. encounters the breakpoint, then immediately switches back to the current
  18265. thread. The following example selects thread 4, sets a breakpoint at line
  18266. 168 in thread 3, and switches to thread 4 when the breakpoint is hit:  %@NL@%
  18267. %@NL@%
  18268. %@AS@%  001>~4S
  18269. %@AS@%  001>~3BP .168 "~.S"
  18270. %@AS@%  001>G%@AE@%%@NL@%
  18271. %@NL@%
  18272. %@NL@%
  18273. %@3@%%@CR:C6A00150019 @%%@AB@%15.6.4  Screen Groups Used by CodeView%@AE@%%@EH@%%@NL@%
  18274. %@NL@%
  18275. Only one CodeView session at a time is supported in protected mode. You
  18276. cannot run multiple copies in concurrent screen groups.  %@NL@%
  18277. %@NL@%
  18278. The View Output Screen command ( %@AB@%\%@AE@% ) works differently in protected mode and
  18279. in real mode. In protected mode, your application's output will be displayed
  18280. for three seconds. The display will then revert to the CodeView display. To
  18281. view the output window for a longer period, specify a different delay
  18282. interval, measured in seconds, as follows:  %@NL@%
  18283. %@NL@%
  18284. %@AS@%  \10%@AE@%%@NL@%
  18285. %@NL@%
  18286.   %@NL@%
  18287. %@NL@%
  18288. %@NL@%
  18289. %@NL@%
  18290. %@NL@%
  18291. %@NL@%
  18292. %@NL@%
  18293. %@CR:C6A00160001 @%%@1@%%@AB@%Chapter 16  Dynamic Linking with OS/2%@AE@%%@EH@%%@NL@%
  18294. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18295. %@NL@%
  18296. An OS/2 dynamic-link library (DLL) is an executable file containing
  18297. functions that are available to other programs. In a statically linked
  18298. program, you link the program with all its component functions when you
  18299. build the executable file. In a dynamically linked program, the
  18300. program-build step does not link all of the code. Instead, OS/2 links calls
  18301. to functions in dynamic-link libraries at program load time or while the
  18302. program is running. The DLL code and data become part of the address space
  18303. of each program, even when the DLL is being accessed by several application
  18304. programs.  %@NL@%
  18305. %@NL@%
  18306. This chapter describes how to build your own dynamic-link libraries and how
  18307. to build programs that use them.  %@NL@%
  18308. %@NL@%
  18309. %@NL@%
  18310. %@2@%%@CR:C6A00160002 @%%@AB@%16.1  Overview of Dynamic Linking%@AE@%%@EH@%%@NL@%
  18311. %@NL@%
  18312. Dynamic linking is the process of resolving external calls when a program
  18313. runs, instead of at link time. It offers several benefits:  %@NL@%
  18314. %@NL@%
  18315. %@NL@%
  18316.   ■   Multiple programs can use the same dynamic-link library
  18317.       simultaneously. Since only one copy of the DLL is in memory, there are
  18318.       fewer demands for physical memory and swap space.%@NL@%
  18319. %@NL@%
  18320.   ■   Updates to dynamic-link libraries do not affect the programs that use
  18321.       them, since the only connection between DLLs and application programs
  18322.       is the function-calling sequence.%@NL@%
  18323. %@NL@%
  18324.   ■   Application programs require less disk space and memory, since their
  18325.       executable program files contain the names of DLL functions but not
  18326.       the code for the functions.%@NL@%
  18327. %@NL@%
  18328.   ■   Dynamic-link libraries can call other dynamic-link libraries.%@NL@%
  18329. %@NL@%
  18330.   ■   DLLs can extend the OS/2 operating system to provide new or improved
  18331.       system services. This is possible because most of OS/2 consists of a
  18332.       set of dynamic-link libraries.%@NL@%
  18333. %@NL@%
  18334. %@NL@%
  18335. %@NL@%
  18336. %@3@%%@CR:C6A00160003 @%%@AB@%16.1.1  Load-Time and Run-Time Linking%@AE@%%@EH@%%@NL@%
  18337. %@NL@%
  18338. Dynamic linking can take place both at program load time and while the
  18339. program is running. A program can call functions in more than one DLL and
  18340. combine both load-time and run-time linking.  %@NL@%
  18341. %@NL@%
  18342. %@AU@% For load-time dynamic linking, build a program that calls DLL functions by
  18343. %@AU@%name.%@AE@%  %@NL@%
  18344. %@NL@%
  18345. The linker creates special records containing the name of each DLL
  18346. subroutine and the name of its DLL file. It does not put any DLL code into
  18347. the program's executable file. At load time, OS/2 dynamically links the
  18348. program and its DLLs. It brings the program and the DLLs into memory and
  18349. updates the program's DLL calls with the address of each DLL routine. If a
  18350. DLL is already in memory, it is not reloaded.  %@NL@%
  18351. %@NL@%
  18352. With run-time dynamic linking, the program creates the DLL file name and
  18353. subroutine names during execution. The program then passes these names to
  18354. OS/2 so the operating system can load the dynamic-link library.  %@NL@%
  18355. %@NL@%
  18356. An example of a run-time dynamic link is an extension to the Programmer's
  18357. WorkBench (PWB). PWB has no information about which extensions it needs
  18358. until it reads the initialization file, TOOLS.INI. PWB then sends requests
  18359. to OS/2 to demand-load the DLLs that it needs.  %@NL@%
  18360. %@NL@%
  18361. %@NL@%
  18362. %@3@%%@CR:C6A00160004 @%%@AB@%16.1.2  Application Programs and DLLs%@AE@%%@EH@%%@NL@%
  18363. %@NL@%
  18364. With static linking, all library code is bound into the executable program
  18365. when you link the program. If the library changes, all programs using the
  18366. library must be relinked. With the exception of some Microsoft Windows
  18367. programs, all DOS programs use static linking.  %@NL@%
  18368. %@NL@%
  18369. %@AU@% Updates to parts of a program are easier to deliver using DLLs.%@AE@%  %@NL@%
  18370. %@NL@%
  18371. You can create loosely coupled applications and DLLs and modify the DLLs
  18372. without relinking the program. For example, if your product has an
  18373. underlying database access mechanism, you can package the database access
  18374. routines into a DLL. You can then ship improvements or changes to the
  18375. database code in a new dynamic-link library. The executable files for the
  18376. program do not have to be relinked or redistributed.  %@NL@%
  18377. %@NL@%
  18378. The programs calling a DLL are known as the DLL's "clients."  %@NL@%
  18379. %@NL@%
  18380. %@NL@%
  18381. %@3@%%@CR:C6A00160005 @%%@AB@%16.1.3  DLLs and Microsoft C Run-Time Libraries%@AE@%%@EH@%%@NL@%
  18382. %@NL@%
  18383. You can construct three types of dynamic-link libraries with the Microsoft C
  18384. Professional Development System. All of them can be multithreaded; they can
  18385. support more than one client at a time. There are three types:  %@NL@%
  18386. %@NL@%
  18387. %@NL@%
  18388.   ■   A stand-alone dynamic-link library that includes both your routines
  18389.       and code for the Microsoft C run-time library functions used by your
  18390.       DLL. This type of DLL is self-contained and completely independent of
  18391.       the programs that call it.%@NL@%
  18392. %@NL@%
  18393.   ■   A dynamic-link library that does not use any functions from the
  18394.       Microsoft C run-time library. This type of DLL is also self-contained.%@NL@%
  18395. %@NL@%
  18396.   ■   A private dynamic-link library that consists only of selected
  18397.       functions from the Microsoft C run-time library. This DLL is usually
  18398.       specific to one program or a closely tied group of programs.
  18399.       Application programs and dynamic-link libraries using this DLL do not
  18400.       contain any code for the C run-time library functions.%@NL@%
  18401. %@NL@%
  18402. %@NL@%
  18403. The following sections provide more information about the differences
  18404. between the various types of DLLs.  %@NL@%
  18405. %@NL@%
  18406. %@NL@%
  18407. %@4@%%@AB@%Stand-Alone Dynamic-Link Libraries%@AE@%%@EH@%%@NL@%
  18408. %@NL@%
  18409. %@AU@% Stand-alone DLLs include C run-time functions.%@AE@%  %@NL@%
  18410. %@NL@%
  18411. If you want to call C run-time library functions in your DLL, you can
  18412. include the functions you need. These run-time functions are statically
  18413. linked in the DLL and the DLL does not rely on the client or any other DLL
  18414. for run-time support.  %@NL@%
  18415. %@NL@%
  18416. Figure 16.1 illustrates the relationships between this type of DLL, an
  18417. application program, and C run-time library functions. Both the application
  18418. program and the dynamic-link library have their own copies of functions from
  18419. the C run-time library. This ensures that  %@NL@%
  18420. %@NL@%
  18421. %@NL@%
  18422.   ■   The DLL always has access to the C run-time library routines it needs.%@NL@%
  18423. %@NL@%
  18424.   ■   The DLL is not dependent on the calling application for any support
  18425.       code.%@NL@%
  18426. %@NL@%
  18427.   ■   The programs using the DLL do not depend on the DLL for C run-time
  18428.       library functions.%@NL@%
  18429. %@NL@%
  18430. %@NL@%
  18431. Section 16.3.1, "DLLs with Static C Run-Time Library Functions," describes
  18432. the steps involved in creating this type of dynamic-link library using the
  18433. special library LLIBCDLL.LIB.  %@NL@%
  18434. %@NL@%
  18435. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  18436. %@NL@%
  18437. %@NL@%
  18438. %@4@%%@AB@%DLLs without C Run-Time Library Functions%@AE@%%@EH@%%@NL@%
  18439. %@NL@%
  18440. You can write a dynamic-link library in C without calling any functions from
  18441. the C run-time library. Section 16.3.2, "DLLs without C Run-Time Library
  18442. Functions," shows how to set up this type of DLL. These DLLs contain only
  18443. your code and require no run-time library support; they make no calls to
  18444. run-time library functions.  %@NL@%
  18445. %@NL@%
  18446. %@NL@%
  18447. %@4@%%@AB@%Private C Run-Time DLLs%@AE@%%@EH@%%@NL@%
  18448. %@NL@%
  18449. %@AU@% You can create a custom C run-time DLL.%@AE@%  %@NL@%
  18450. %@NL@%
  18451. A C run-time DLL can be shared by multiple programs and their DLLs. You
  18452. generate the C run-time DLL in two steps. The first builds a
  18453. module-definition file with a list of the C run-time library functions
  18454. needed by your application and its DLLs; the second step links the
  18455. module-definition file with the special library CDLLOBJS.LIB to create a C
  18456. run-time DLL.  %@NL@%
  18457. %@NL@%
  18458. The executable files for programs and DLLs linked with a customized C
  18459. run-time DLL do not contain any code for the C run-time library functions.
  18460. Figure 16.2 shows the relationships of the components.  %@NL@%
  18461. %@NL@%
  18462. %@AU@% A private C run-time DLL must be closely tied to its programs and
  18463. %@AU@%associated DLLs.%@AE@%  %@NL@%
  18464. %@NL@%
  18465. Processes and DLLs that share a private run-time DLL share environment
  18466. strings and global C run-time data (for example, file pointers for buffered
  18467. I/O and memory allocated with the %@AB@%malloc%@AE@% function). Therefore, the program
  18468. and the DLLs must cooperate on the use of this data.  %@NL@%
  18469. %@NL@%
  18470. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  18471. %@NL@%
  18472. A closely tied structure is suitable for a complex application consisting of
  18473. a set of application programs that act as front-end processors to several
  18474. DLLs. A word processor, for example, might support one user interface for
  18475. beginners, another for intermediate users, and a third for expert users. The
  18476. different user interfaces could be implemented in three separate executable
  18477. program files. All three programs would share the DLLs that do most of the
  18478. real work.  %@NL@%
  18479. %@NL@%
  18480. Section 16.3.3, "Programs and DLLs with a C Run-Time DLL," describes the
  18481. procedures for building a C run-time library DLL and its associated programs
  18482. and dynamic-link libraries.  %@NL@%
  18483. %@NL@%
  18484. %@NL@%
  18485. %@2@%%@CR:C6A00160006 @%%@AB@%16.2  Designing and Writing DLLs%@AE@%%@EH@%%@NL@%
  18486. %@NL@%
  18487. Before you write a DLL, you must determine some of the DLL's requirements.
  18488. You need to know  %@NL@%
  18489. %@NL@%
  18490. %@NL@%
  18491.   ■   Floating-point math requirements%@NL@%
  18492. %@NL@%
  18493.   ■   Special initialization requirements such as allocation of buffers or
  18494.       registration of special termination routines%@NL@%
  18495. %@NL@%
  18496.   ■   Termination requirements such as clearing semaphores or releasing
  18497.       allocated memory%@NL@%
  18498. %@NL@%
  18499.   ■   Re-entrancy requirements; if the DLL is to be called by more than one
  18500.       process, it must be re-entrant%@NL@%
  18501. %@NL@%
  18502. %@NL@%
  18503. This section explains how to design a DLL to take these requirements into
  18504. account.  %@NL@%
  18505. %@NL@%
  18506. %@NL@%
  18507. %@3@%%@CR:C6A00160007 @%%@AB@%16.2.1  Floating-Point Math Requirements%@AE@%%@EH@%%@NL@%
  18508. %@NL@%
  18509. Stand-alone DLLs built with the LLIBCDLL library are independent of the
  18510. programs calling them. They are "black boxes" that must operate without
  18511. knowing anything about their client programs and without interfering with
  18512. their clients.%@CR:C6A00160008 @%  %@NL@%
  18513. %@NL@%
  18514. One area of potential conflict for stand-alone DLLs is control of the 80%@AI@%x%@AE@%87
  18515. math coprocessor. For a DLL to use the 80%@AI@%x%@AE@%87 coprocessor or the emulator
  18516. floating-point library, the DLL and all of its client programs must agree on
  18517. which process is going to handle floating-point exceptions and on which
  18518. process is going to handle emulation if the machine does not have a
  18519. coprocessor.  %@NL@%
  18520. %@NL@%
  18521. Floating-point emulation is not possible with a genuinely independent DLL. A
  18522. stand-alone DLL must use the alternate math library, which ignores the math
  18523. coprocessor chip. The alternate math library provides the fastest processing
  18524. available without a coprocessor, but results are not as accurate as those
  18525. produced by the emulator floating-point library. Because the constraint
  18526. applies only to the DLL and not to applications, clients of a stand-alone
  18527. DLL can use any floating-point model. Since the DLL uses the alternate math
  18528. library, it does not conflict with clients over control of the math
  18529. coprocessor.  %@NL@%
  18530. %@NL@%
  18531. In contrast, DLLs and programs using a private C run-time DLL are tightly
  18532. coupled. This means that the floating-point math option is known when the
  18533. program is built. Because these programs and DLLs all use the same C runtime
  18534. functions (unlike the stand-alone DLL and its clients, which may incorporate
  18535. different C run-time libraries), no contention can arise over control of the
  18536. math coprocessor. The same floating-point math library is used for the
  18537. entire application.  %@NL@%
  18538. %@NL@%
  18539. %@AU@% The only way to use a math coprocessor within a DLL is with a private C
  18540. %@AU@%run-time DLL.%@AE@%  %@NL@%
  18541. %@NL@%
  18542. A private C run-time DLL uses the CDLLOBJS library and the emulator
  18543. floating-point package. The emulator uses the 80%@AI@%x%@AE@%87 math coprocessor if one
  18544. is installed; otherwise, it emulates the coprocessor. Floating-point
  18545. emulation produces the most accurate results. There is no conflict over use
  18546. of the coprocessor, since the C run-time DLL performs all floating-point
  18547. math. The programs and DLLs calling the C run-time DLL do not have any C
  18548. run-time library code of their own.  %@NL@%
  18549. %@NL@%
  18550. %@NL@%
  18551. %@3@%%@CR:C6A00160009 @%%@AB@%16.2.2  Initialization and Termination Requirements%@AE@%%@EH@%%@NL@%
  18552. %@NL@%
  18553. When you design a DLL, you must decide if it has special initialization or
  18554. termination requirements. If the DLL needs to initialize variables or
  18555. allocate memory buffers when it starts, it needs custom start-up procedures.
  18556. If the DLL acquires system resources for a client program, the resources
  18557. must be released when the program completes its processing.  %@NL@%
  18558. %@NL@%
  18559. %@NL@%
  18560. %@4@%%@AB@%Initialization%@AE@%%@EH@%%@NL@%
  18561. %@NL@%
  18562. All DLLs built with the Microsoft C run-time libraries must use per-process
  18563. initialization to set up the C run-time data. Per-process initialization
  18564. (also known as instance initialization) means that OS/2 calls the DLL's
  18565. initialization code each time it loads a program linked with the DLL. For
  18566. most DLLs, the default initialization routine is sufficient, and you do not
  18567. need to take any other measures.  %@NL@%
  18568. %@NL@%
  18569. %@AU@% If your DLL has special requirements, you must provide additional start-up
  18570. %@AU@%processing.%@AE@%  %@NL@%
  18571. %@NL@%
  18572. The C run-time library initialization function is called each time a new
  18573. client is attached to the DLL. To override the default initialization, you
  18574. must link your DLL with one of the following object modules, which are
  18575. provided with the Microsoft C Professional Development System:  %@NL@%
  18576. %@NL@%
  18577. %@AB@%File Name%@AE@%                         %@AB@%Description%@AE@%
  18578. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  18579. DLLINIT.OBJ                       Initialization module for DLLs built 
  18580.                                   with LLIBCDLL.LIB and using C run-time 
  18581.                                   library code
  18582.  
  18583. CRTDLL_I.OBJ                      Initialization module for DLLs using a C
  18584.                                   run-time DLL built with CDLLOBJS.LIB 
  18585.                                   (replaces CRTDLL.OBJ)
  18586.  
  18587. In addition, you must declare an entry point for your own DLL initialization
  18588. function. Your function, or the application program calling your DLL, must
  18589. initialize the C run-time data by calling the library function %@AB@%C_INIT%@AE@% before
  18590. any other C run-time library functions are called.  %@NL@%
  18591. %@NL@%
  18592. The prototype for %@AB@%C_INIT%@AE@% is  %@NL@%
  18593. %@NL@%
  18594. %@AS@%  void _far _pascal C_INIT( void );%@AE@%%@NL@%
  18595. %@NL@%
  18596. %@AU@% Designate your initialization function as the DLL's starting point.%@AE@%  %@NL@%
  18597. %@NL@%
  18598. To have your custom function recognized as the DLL's default initialization
  18599. routine, it must be the starting point for the DLL. This requires an
  18600. assembly language file with an %@AB@%END%@AE@% statement naming your function. The
  18601. sample file, SETENTRY.ASM, in the following example shows the minimum
  18602. assembler code required for specifying a C language function named
  18603. %@AB@%SampleInit%@AE@% as the DLL's entry point.  %@NL@%
  18604. %@NL@%
  18605. %@AS@%  ; SETENTRY.ASM
  18606. %@AS@%  extrn _SampleInit:FAR         ;name of C start-up routine
  18607. %@AS@%  end   _SampleInit%@AE@%%@NL@%
  18608. %@NL@%
  18609. The following example, SAMPLE.C, shows a simple custom initialization
  18610. routine that maintains a count of how many clients it is currently serving.
  18611. Since this example overrides the default dynamic-link library
  18612. initialization, it must return a nonzero status code to OS/2 to show a
  18613. successful start-up. If a DLL initialization function returns a status of 0,
  18614. OS/2 will not load the program using the DLL.  %@NL@%
  18615. %@NL@%
  18616. %@AS@%  /*                    SAMPLE.C                    */ 
  18617. %@AS@%  void _far _pascal C_INIT( void ); 
  18618. %@AS@%  int  UserCount = 0;
  18619. %@AS@%  
  18620. %@AS@%  int _export _loadds SampleInit() 
  18621. %@AS@%  {
  18622. %@AS@%      UserCount++;        /* increment number of users  */
  18623. %@AS@%      C_INIT();           /* initialize C run-time data */
  18624. %@AS@%      return( 1 );        /* indicate successful start  */
  18625. %@AS@%  }
  18626. %@AS@%  
  18627. %@AS@%  /* code for other DLL functions belongs here */%@AE@%%@NL@%
  18628. %@NL@%
  18629. All DLLs must be linked with a module-definition file that contains a
  18630. %@AB@%LIBRARY%@AE@% statement, such as the following:  %@NL@%
  18631. %@NL@%
  18632. %@AS@%  LIBRARY SAMPLE INITINSTANCE%@AE@%%@NL@%
  18633. %@NL@%
  18634. The following commands will create object files from the sample files and
  18635. link them with DLLINIT.OBJ to make a stand-alone dynamic-link library  named
  18636. SAMPLE.DLL. The /ML compile option, explained in Section 16.2.6, "Compile
  18637. Options for Dynamic-Link Libraries," sets the library search record to
  18638. LLIBCDLL.LIB.  %@NL@%
  18639. %@NL@%
  18640. %@AS@%  MASM /Mx SETENTRY;
  18641. %@AS@%  CL /c /Gs /ML SAMPLE.C
  18642. %@AS@%  LINK /NOE DLLINIT+SETENTRY+SAMPLE,SAMPLE.DLL,,,SAMPLE.DEF;%@AE@%%@NL@%
  18643. %@NL@%
  18644. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18645. %@AU@%WARNING%@AE@%%@NL@%
  18646. %@NL@%
  18647. For DLLs linked with Microsoft C run-time libraries, the %@AI@%LIBRARY%@AE@% statement
  18648. in the DLL's module-definition file must specify %@AI@%INITINSTANCE %@AE@%in the
  18649. initialization field. If you omit this, the initialization routine is called
  18650. only when the DLL is loaded into memory for the first client program, and
  18651. the DLL will not function properly if it is called by additional programs.%@NL@%
  18652. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18653. %@NL@%
  18654. %@NL@%
  18655. %@4@%%@AB@%Termination%@AE@%%@EH@%%@NL@%
  18656. %@NL@%
  18657. %@AU@% You may have to clean up before terminating.%@AE@%  %@NL@%
  18658. %@NL@%
  18659. You may need to know when an application using your DLL is finished. If your
  18660. DLL has created buffers, semaphores, or other resources for a particular
  18661. application, they must be released when the application terminates.  %@NL@%
  18662. %@NL@%
  18663. You can have an initialization routine in your DLL that calls the OS/2 API
  18664. function %@AB@%DosExitList%@AE@% to register one or more exit subroutines for your DLL.
  18665. OS/2 will call the exit routines when the client program finishes. The exit
  18666. functions should free any resources your DLL acquired for the client
  18667. program.  %@NL@%
  18668. %@NL@%
  18669. %@AU@% DLLs built with LLIBCDLL.LIB have a default termination routine.%@AE@%  %@NL@%
  18670. %@NL@%
  18671. The start-up routine for dynamic-link libraries built with the LLIBCDLL
  18672. library calls %@AB@%DosExitList%@AE@% with a pointer to a default termination function.
  18673. To replace the default processing with your own function, link the module
  18674. DLLTERM.OBJ into the DLL. This suppresses the call to %@AB@%DosExitList%@AE@%. During
  18675. initialization, your DLL must register its own routine by calling
  18676. %@AB@%DosExitList%@AE@% unless you are sure the termination routine will be called
  18677. explicitly. The termination processing must include a call to the library
  18678. function %@AB@%C_TERM%@AE@%.  %@NL@%
  18679. %@NL@%
  18680. The prototype for %@AB@%C_TERM%@AE@% is  %@NL@%
  18681. %@NL@%
  18682. %@AS@%  void _far _pascal C_TERM( void );%@AE@%%@NL@%
  18683. %@NL@%
  18684. There is no equivalent to DLLTERM.OBJ and %@AB@%C_TERM%@AE@% for DLLs using a private C
  18685. run-time DLL built with the CDLLOBJS library. If special cleanup processing
  18686. is required, these DLLs must provide their own termination function. The
  18687. function is registered during initialization by calling either the C
  18688. run-time library function %@AB@%atexit%@AE@% or the OS/2 API function %@AB@%DosExitList%@AE@%.  %@NL@%
  18689. %@NL@%
  18690. %@AU@% Any DLL that calls %@AE@%%@AB@%DosExitList %@AE@%should also have a termination function.  %@NL@%
  18691. %@NL@%
  18692. DLLs that set exit lists must provide termination functions that can be
  18693. called by clients when they no longer need the DLL. If a program attaches
  18694. itself to the DLL at run-time (using %@AB@%DosLoadModule%@AE@%), it cannot disconnect
  18695. from the DLL as long as the exit list points to a function in the
  18696. dynamic-link library. The DLL's termination function can perform any
  18697. necessary cleanup and call %@AB@%DosExitList%@AE@% to remove itself from the exit list.
  18698. %@NL@%
  18699. %@NL@%
  18700. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18701. NOTE
  18702. %@AI@%There is no special termination procedure for DLLs build with CDLLOBJS.LIB
  18703. %@AI@%because the C run-time termination code is called by the %@AB@%exit%@AE@%%@AI@% or %@AE@%%@AI@%%@AB@%_exit%@AE@%%@AE@%%@AI@%
  18704. %@AI@%functions. If the process is terminated by a critical error or %@AE@%%@AI@%%@AB@%DosExit%@AE@%%@AE@%%@AI@%, C
  18705. %@AI@%run-time termination does not occur.%@AE@%%@AE@%%@NL@%
  18706. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  18707. %@NL@%
  18708. %@NL@%
  18709. %@3@%%@CR:C6A00160010 @%%@AB@%16.2.3  Making the DLL Re-Entrant%@AE@%%@EH@%%@NL@%
  18710. %@NL@%
  18711. Re-entrant code is code that can be shared by multiple programs in a
  18712. multitasking environment. DLLs that may be used by more than one program
  18713. must be re-entrant. To do this, they must isolate each client program's data
  18714. and resources. File handles belonging to one client, for example, must not
  18715. be used for other clients. Re-entrancy also means that the DLL cannot allow
  18716. itself to be switched to a different thread while it is performing certain
  18717. operations.  %@NL@%
  18718. %@NL@%
  18719. %@NL@%
  18720. %@4@%%@AB@%Global Versus Instance Data%@AE@%%@EH@%%@NL@%
  18721. %@NL@%
  18722. %@AU@% A dynamic-link library can have separate data segments for each program
  18723. %@AU@%that calls it.%@AE@%  %@NL@%
  18724. %@NL@%
  18725. Separate data segments are known as "instance" data. With instance data
  18726. segments, the DLL does not have to keep track of which resources belong to
  18727. each client. OS/2 assigns a different data segment to each process calling
  18728. the DLL, even though the selectors are the same.  %@NL@%
  18729. %@NL@%
  18730. A dynamic-link library can also have a global data segment used for internal
  18731. purposes or to support all of the programs using its services.  %@NL@%
  18732. %@NL@%
  18733. A DLL providing time and date conversions might, for example, keep the
  18734. current date in a global storage area. The same DLL might provide functions
  18735. to compute elapsed time, such as the number of minutes between two clock
  18736. readings. If static variables are used by the elapsed time functions, they
  18737. should be in instance data segments, since the OS/2 scheduler might preempt
  18738. the function and schedule another thread that calls the same function with
  18739. different arguments before it has completed the first caller's task.  %@NL@%
  18740. %@NL@%
  18741. Data sharing is controlled by %@AB@%DATA%@AE@% and %@AB@%SEGMENTS%@AE@% statements in a dynamic-link
  18742. library's module-definition file. By default, a DLL's automatic data segment
  18743. (the local stack and heap) is shared by all processes calling the DLL. You
  18744. can specify a unique automatic data segment for each client process by
  18745. specifying %@AB@%DATA MULTIPLE%@AE@%.  %@NL@%
  18746. %@NL@%
  18747. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18748. %@AU@%WARNING%@AE@%%@NL@%
  18749. %@NL@%
  18750. DLLs built with the LLIBCDLL or CDLLOBJS C run-time libraries must use %@AI@%DATA
  18751. %@AI@%MULTIPLE%@AE@% in the module-definition file.%@NL@%
  18752. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18753. %@NL@%
  18754. %@AU@% You can use %@AE@%%@AI@%SEGMENTS%@AE@% to specify attributes on a segment-by-segment basis.  %@NL@%
  18755. %@NL@%
  18756. Using the %@AB@%SEGMENTS%@AE@% statement allows you to have both global and per-process
  18757. (instance) data in the same DLL. The C run-time data segment must be
  18758. per-process. The following is an example of a C program fragment and
  18759. moduledefinition file that implement both instance and global data:  %@NL@%
  18760. %@NL@%
  18761. %@AS@%  /* Define static data in the shared segment SHR_SEG */
  18762. %@AS@%  int _based(_segname("SHR_SEG")) intvar;
  18763. %@AS@%  char _based(_segname("SHR_SEG")) charvar;%@AE@%%@NL@%
  18764. %@NL@%
  18765. In the module-definition file, define all data segments as nonshareable,
  18766. then override that default for %@AS@% SHR_SEG %@AE@% as follows:  %@NL@%
  18767. %@NL@%
  18768. %@AS@%  DATA MULTIPLE NONSHARED
  18769. %@AS@%  SEGMENTS
  18770. %@AS@%      SHR_SEG     CLASS   'FAR_DATA'  SHARED%@AE@%%@NL@%
  18771. %@NL@%
  18772. Global data segments are created when OS/2 brings the dynamic-link library
  18773. into memory for its first client process. All of the processes calling the
  18774. DLL share the same global variables.  %@NL@%
  18775. %@NL@%
  18776. %@NL@%
  18777. %@4@%%@AB@%Serializing Nonatomic References%@AE@%%@EH@%%@NL@%
  18778. %@NL@%
  18779. An atomic operation is an operation that can be completed in one machine
  18780. language instruction. When writing a re-entrant procedure (in a multithread
  18781. program or in a DLL), you must ensure that changes to static or global data
  18782. are not preempted by the OS/2 scheduler before the update is complete. To
  18783. prevent this, you must explicitly serialize nonatomic references to static
  18784. or global data. The following code example is safe from preemption, because
  18785. incrementing an integer requires only one machine instruction:  %@NL@%
  18786. %@NL@%
  18787. %@AS@%  int int_var;
  18788. %@AS@%  _export _loadds void _far _pascal dynlink_proc( void ) 
  18789. %@AS@%  {
  18790. %@AS@%     int_var++; 
  18791. %@AS@%  }%@AE@%%@NL@%
  18792. %@NL@%
  18793. The following variation on the same function is not safe because
  18794. incrementing  a %@AB@%long%@AE@% variable is not atomic; it requires two machine
  18795. instructions. Between incrementing the least-significant word and the
  18796. most-significant word, another thread could gain control of the processor.
  18797. If that thread executes code in your DLL that uses %@AS@% long_var%@AE@%, that data
  18798. would be in an indeterminate state.  %@NL@%
  18799. %@NL@%
  18800. %@AS@%  long long_var;
  18801. %@AS@%  _export _loadds void _far _pascal dynlink_proc( void )
  18802. %@AS@%  {
  18803. %@AS@%     long_var++; 
  18804. %@AS@%  }%@AE@%%@NL@%
  18805. %@NL@%
  18806. %@NL@%
  18807. %@4@%%@AB@%Critical Code Sections%@AE@%%@EH@%%@NL@%
  18808. %@NL@%
  18809. A critical code section is a section of code that manipulates a resource
  18810. (such as the long variable in the previous example) while blocking all other
  18811. threads. When your program enters a critical section, it cannot be preempted
  18812. until it performs a %@AB@%DosExitCritSec%@AE@% or until a signal is received. You don't
  18813. usually just alter the value of a variable; you alter it and then use it
  18814. later. In this case, you must isolate the smallest group of operations that
  18815. must occur without interruption. You define these sections with the
  18816. %@AB@%DosEnterCritSec%@AE@% and %@AB@%DosExitCritSec%@AE@% OS/2 API functions, as in the following
  18817. example:  %@NL@%
  18818. %@NL@%
  18819. %@AS@%  _export _loadds void _far _pascal dynlink_proc( void )
  18820. %@AS@%  {   static int_var;%@AE@%%@NL@%
  18821. %@NL@%
  18822. %@AS@%     DosEnterCritSec();
  18823. %@AS@%     int_var += 7;
  18824. %@AS@%     SetLeftCorner( int_var, int_var );
  18825. %@AS@%     DosExitCritSec();%@AE@%%@NL@%
  18826. %@NL@%
  18827. %@AS@%  /* Code that does not reference int_var */
  18828. %@AS@%  }%@AE@%%@NL@%
  18829. %@NL@%
  18830. %@AU@% Keep your critical sections as short as possible.%@AE@%  %@NL@%
  18831. %@NL@%
  18832. While in a critical section, all other threads in the process are blocked
  18833. from execution. Writing extremely long critical sections can make your
  18834. program inefficient and can degrade system performance.  %@NL@%
  18835. %@NL@%
  18836. Although other threads are blocked from execution by %@AB@%DosEnterCritSec%@AE@% and
  18837. %@AB@%DosExitCritSec%@AE@%, these functions do not block signal handling.  %@NL@%
  18838. %@NL@%
  18839. Note that static variables in DLLs are protected from interference from
  18840. other processes if they are in an instance data segment designated as
  18841. %@AB@%MULTIPLE%@AE@% in the %@AB@%DATA%@AE@% statement of the DLL's module-definition file. Memory
  18842. is "owned" by a process and, unless specifically allocated as shareable,
  18843. cannot be altered by any other process.  %@NL@%
  18844. %@NL@%
  18845. %@NL@%
  18846. %@3@%%@CR:C6A00160011 @%%@AB@%16.2.4  Signal Handling%@AE@%%@EH@%%@NL@%
  18847. %@NL@%
  18848. The C library function %@AB@%signal%@AE@% is not supported for multithread programs or
  18849. for DLLs. If you need to process signals, use the OS/2 API signal functions,
  18850. such as %@AB@%DosSetSigHandler%@AE@%.  %@NL@%
  18851. %@NL@%
  18852. See Chapter 15, "Creating Multithread OS/2 Applications," for more
  18853. information about signal handling in OS/2 programs.  %@NL@%
  18854. %@NL@%
  18855. %@NL@%
  18856. %@3@%%@CR:C6A00160012 @%%@AB@%16.2.5  Using Microsoft C Keywords%@AE@%%@EH@%%@NL@%
  18857. %@NL@%
  18858. The %@AB@%_export%@AE@% and %@AB@%_loadds%@AE@% keywords simplify writing DLLs. They are used to
  18859. define or declare functions or pointers to functions. In the DLL, an
  18860. exported function with a single argument might be defined as  %@NL@%
  18861. %@NL@%
  18862. %@AS@%  int _export _loadds sample( int )%@AE@%%@NL@%
  18863. %@NL@%
  18864. %@NL@%
  18865. %@4@%%@AB@%The _export Keyword%@AE@%%@EH@%%@NL@%
  18866. %@NL@%
  18867. %@AU@% All DLL functions that will be called from outside the library must be
  18868. %@AU@%exported.%@AE@%  %@NL@%
  18869. %@NL@%
  18870. The %@AB@%_export%@AE@% keyword gives a function the export attribute. Stack checking
  18871. must be disabled for exported entry points. You can use the /Gs compile
  18872. option or the %@AB@%check_stack%@AE@% pragma to accomplish this.  %@NL@%
  18873. %@NL@%
  18874. Using the %@AB@%_export%@AE@% keyword is an alternative to declaring the name of the
  18875. function in the %@AB@%EXPORTS%@AE@% section of a module-definition file. It assigns
  18876. certain default attributes: no I/O privilege, shared data, load on demand,
  18877. and no alias name. If the defaults are not acceptable, you must specify the
  18878. proper attributes in the module-definition file.  %@NL@%
  18879. %@NL@%
  18880. Not all functions in a DLL are for external use. A DLL can have any number
  18881. of utility subroutines supporting the work of the exported functions.
  18882. Functions that are private to the DLL should not have the %@AB@%_export%@AE@% keyword.  %@NL@%
  18883. %@NL@%
  18884. %@NL@%
  18885. %@4@%%@AB@%The _loadds Keyword%@AE@%%@EH@%%@NL@%
  18886. %@NL@%
  18887. At entry to a DLL, the DS (data segment) register points to the calling
  18888. program's data segment. To access the DLL's data, the DS register has to be
  18889. loaded with the DLL's segment selector. The %@AB@%_loadds%@AE@% keyword causes the
  18890. compiler to add prolog and epilog code to the function. The prolog code
  18891. initializes the DS register to point to the function's data group. The
  18892. epilog code restores the caller's DS register when the function terminates.
  18893. %@NL@%
  18894. %@NL@%
  18895. Since loading the DS register is a high overhead operation, you should limit
  18896. the use of %@AB@%_loadds%@AE@% to the exported functions in your DLL.  %@NL@%
  18897. %@NL@%
  18898. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18899. %@AU@%WARNING%@AE@%%@NL@%
  18900. %@NL@%
  18901. Do not use the %@AB@%_loadds%@AE@% keyword in a function definition if the function uses
  18902. only stack variables. If you specify %@AB@%_loadds%@AE@% in a DLL that does not have any
  18903. static data, the linker will issue a segment fix-up error.%@NL@%
  18904. ────────────────────────────────────────────────────────────────────────────%@NL@%
  18905. %@NL@%
  18906. %@NL@%
  18907. %@3@%%@CR:C6A00160013 @%%@AB@%16.2.6  Compile Options for Dynamic-Link Libraries%@AE@%%@EH@%%@NL@%
  18908. %@NL@%
  18909. Dynamic-link libraries must be compiled with specific options that control
  18910. linking, memory models, and library selection.  %@NL@%
  18911. %@NL@%
  18912. %@NL@%
  18913. %@4@%%@AB@%Compile without Linking (/c)%@AE@%%@EH@%%@NL@%
  18914. %@NL@%
  18915. You must use the /c option to build your DLL in separate compile and link
  18916. steps. This is necessary because the DLL must be linked with a
  18917. module-definition file specifying that the output file is a dynamic-link
  18918. library. (The compiler does not pass module-definition file names to the
  18919. linker.) The /c option is automatically specified in the makefile generated
  18920. by the Programmer's WorkBench.  %@NL@%
  18921. %@NL@%
  18922. %@NL@%
  18923. %@4@%%@AB@%Large Memory Model with Separate Stack (/ALw)%@AE@%%@EH@%%@NL@%
  18924. %@NL@%
  18925. The /ALw option instructs the compiler to use the large memory model with a
  18926. separate stack segment. Because all DLLs use the caller's stack, you must
  18927. use /Aw or /Au. The /Aw option sets up separate stack and data segments but
  18928. does not cause the DS register to be reloaded at the entry to each function.
  18929. This allows you to call private functions (functions that you do not export)
  18930. without incurring the overhead of loading the DS register. Functions that
  18931. you do export must also be declared using the %@AB@%_loadds%@AE@% keyword, described
  18932. above, which sets up the proper DS register handling. If you use the /Au
  18933. option, the DS register will be reloaded on entry to every function, which
  18934. can cause the function calls in your DLLs to execute more slowly.  %@NL@%
  18935. %@NL@%
  18936. All DLL functions are reached using far calls. Pointers passed to and from
  18937. the DLL must be far pointers.  %@NL@%
  18938. %@NL@%
  18939. %@NL@%
  18940. %@4@%%@AB@%Remove Stack Probes (/Gs)%@AE@%%@EH@%%@NL@%
  18941. %@NL@%
  18942. Since the DLL uses the caller's stack, you should usually use the /Gs option
  18943. to disable stack checking within the DLL.  %@NL@%
  18944. %@NL@%
  18945. %@NL@%
  18946. %@4@%%@AB@%Specify 80286 Code (/G2)%@AE@%%@EH@%%@NL@%
  18947. %@NL@%
  18948. Use the /G2 option to designate code generation for the 80286 processor
  18949. instruction set, since OS/2 runs only on 80286 and higher model processors.
  18950. %@NL@%
  18951. %@NL@%
  18952. %@NL@%
  18953. %@4@%%@AB@%Link C Run-Time into Stand-Alone DLL (/ML)%@AE@%%@EH@%%@NL@%
  18954. %@NL@%
  18955. Use the /ML option to build a stand-alone dynamic-link library that includes
  18956. static code for C run-time library functions. This option has the same
  18957. effect as using the /ALw, /FPa, /G2, and /D MT options. It changes the
  18958. library search record to LLIBCDLL.LIB. See Section 16.3.1, "DLLs with Static
  18959. C Run-Time Library Functions" for more information about these options.  %@NL@%
  18960. %@NL@%
  18961. %@NL@%
  18962. %@4@%%@AB@%Link Executable or DLL with C Run-Time DLL (/MD)%@AE@%%@EH@%%@NL@%
  18963. %@NL@%
  18964. Use the /MD option to build an executable file or a dynamic-link library
  18965. that calls a C run-time DLL. This option has the same effect as using the
  18966. /ALw, /FPi, /G2, /D DLL, and /D MT options. It inhibits library search
  18967. records. See Section 16.3.3, "Programs and DLLs with a C Run-Time DLL," for
  18968. more information about these options.  %@NL@%
  18969. %@NL@%
  18970. %@NL@%
  18971. %@4@%%@AB@%Suppress Default Library Selection (/Zl)%@AE@%%@EH@%%@NL@%
  18972. %@NL@%
  18973. If you do not compile with the /MD or /ML options described above, compile
  18974. with the /Zl option or use the /NOD option when you link in order to inhibit
  18975. searches for default libraries.  %@NL@%
  18976. %@NL@%
  18977. %@NL@%
  18978. %@2@%%@CR:C6A00160014 @%%@AB@%16.3  Building DLLs with Microsoft C%@AE@%%@EH@%%@NL@%
  18979. %@NL@%
  18980. %@AU@% Building a DLL for OS/2 is like building an executable program file.%@AE@%  %@NL@%
  18981. %@NL@%
  18982. To build a DLL, compile and link the dynamic-link library like any other
  18983. executable file, but add a module-definition file. This module-definition
  18984. file tells the linker that the output is a dynamic-link library.  %@NL@%
  18985. %@NL@%
  18986. When you build applications that use a dynamic-link library, you must tell
  18987. the linker where to find the library's dynamically linked functions. You use
  18988. import libraries and module-definition files for this purpose.  %@NL@%
  18989. %@NL@%
  18990. %@NL@%
  18991. %@3@%%@CR:C6A00160015 @%%@AB@%16.3.1  DLLs with Static C Run-Time Library Functions%@AE@%%@EH@%%@NL@%
  18992. %@NL@%
  18993. The LLIBCDLL library is used to create stand-alone DLLs. The library
  18994. functions are re-entrant and can be called by multiple threads within a
  18995. program as well as by multiple programs. The code for the stand-alone DLL's
  18996. C run-time library functions is contained within the DLL. Programs that call
  18997. stand-alone DLLs have their own run-time library code.  %@NL@%
  18998. %@NL@%
  18999. %@NL@%
  19000. %@4@%%@AB@%Building the DLL%@AE@%%@EH@%%@NL@%
  19001. %@NL@%
  19002. The files required to build a stand-alone DLL with the LLIBCDLL library are
  19003. listed below:  %@NL@%
  19004. %@NL@%
  19005. %@AB@%File Name%@AE@%                         %@AB@%Description%@AE@%
  19006. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19007. OS2.LIB                           OS/2 kernel import library
  19008.  
  19009. LLIBCDLL.LIB                      Large-model multithread C run-time 
  19010.                                   library for DLLs
  19011.  
  19012. DLLINIT.OBJ                       Optional initialization module for DLLs 
  19013.                                   requiring custom initialization
  19014.  
  19015. DLLTERM.OBJ                       Optional termination module for DLLs 
  19016.                                   requiring custom exit processing
  19017.  
  19018. %@AI@%userdll%@AE@%.C                         Source code for the DLL you create
  19019.  
  19020. %@AI@%userdll%@AE@%.DEF                       Module-definition file for the DLL you 
  19021.                                   create
  19022.  
  19023. The module JUSTIFY.C, below, is an example of source code for a simple
  19024. dynamic-link library. The %@AB@%RightJustify%@AE@% routine calls the %@AB@%strlen%@AE@% function
  19025. from the C run-time library and right-justifies a caller's buffer. The
  19026. function definition includes the %@AB@%_export%@AE@% keyword. The %@AB@%_loadds%@AE@% keyword is
  19027. omitted, since this function does not need any static data. If it did, you
  19028. would need to specify %@AB@%_loadds%@AE@%.  %@NL@%
  19029. %@NL@%
  19030. For simplicity, JUSTIFY.C below shows a DLL with a single function. In
  19031. actual practice, you would usually package a group of similar utilities into
  19032. one DLL.  %@NL@%
  19033. %@NL@%
  19034. %@AS@%  /* JUSTIFY.C -- Sample Dynamic-Link Library */
  19035. %@AS@%  
  19036. %@AS@%  #include <string.h>
  19037. %@AS@%  
  19038. %@AS@%  /* Right justifies the string in TargetBuff to TargetSize
  19039. %@AS@%   * and inserts necessary number of FillChars on the left.
  19040. %@AS@%   */%@AE@%%@NL@%
  19041. %@NL@%
  19042. %@AS@%  #pragma stack_check(off)
  19043. %@AS@%  
  19044. %@AS@%  int _export RightJustify( char *TargetBuff, int TargetSize,
  19045. %@AS@%                            char FillChar)
  19046. %@AS@%  {
  19047. %@AS@%     char *s, *d;
  19048. %@AS@%      s = TargetBuff + strlen( TargetBuff ); 
  19049. %@AS@%     d = TargetBuff + TargetSize;
  19050. %@AS@%     while ( s = TargetBuff )
  19051. %@AS@%         *d-- = *s--;
  19052. %@AS@%     while ( d = TargetBuff )
  19053. %@AS@%         *d-- = FillChar;
  19054. %@AS@%  
  19055. %@AS@%     return( 0 );
  19056. %@AS@%  }%@AE@%%@NL@%
  19057. %@NL@%
  19058. The steps for creating a stand-alone dynamic-link library with JUSTIFY.C are
  19059. given below. The DLL in the example is named JUSTLIB1.DLL.  %@NL@%
  19060. %@NL@%
  19061. %@NL@%
  19062.   ■   Compile with the /ML Option.%@NL@%
  19063. %@NL@%
  19064. %@STUB@%      Compile the source file without linking. Dynamic-link libraries linked
  19065.       with LLIBCDLL must be compiled with specific options.%@NL@%
  19066. %@NL@%
  19067. %@STUB@%      Use the /ML option to set the library search record to LLIBCDLL.LIB
  19068.       and to indicate that C run-time code is to be included in the DLL.
  19069.       When you use /ML, the following options take effect:%@NL@%
  19070. %@NL@%
  19071. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  19072. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19073. %@NL@%
  19074. /ALw                              Use large memory model with separate 
  19075.                                   stack
  19076.                                   segment
  19077.  
  19078. /G2                               Use 80286 processor instruction set
  19079.  
  19080. /D MT                             Use the multithread version of the 
  19081.                                   include files
  19082.  
  19083. /FPa                              Generate floating-point calls and select
  19084.                                   the alternate math library
  19085.  
  19086. The /G2 and the /ALw options can be overridden.%@NL@%
  19087. %@NL@%
  19088. %@STUB@%      You should also use the /Gs option to suppress stack checking and the
  19089.       /c option to compile without linking. The complete command to compile
  19090.       the sample file JUSTIFY.C is%@NL@%
  19091. %@NL@%
  19092. %@AS@%      CL /ML /Gs /c JUSTIFY.C%@AE@%%@NL@%
  19093. %@NL@%
  19094.   ■   Create a module-definition file.%@NL@%
  19095. %@NL@%
  19096. %@STUB@%      Create a module-definition file, JUSTLIB1.DEF, which includes the
  19097.       following lines:%@NL@%
  19098. %@NL@%
  19099. %@AS@%      LIBRARY JUSTLIB1 INITINSTANCE
  19100. %@AS@%      DATA MULTIPLE%@AE@%%@NL@%
  19101. %@NL@%
  19102. %@STUB@%      The %@AB@%LIBRARY%@AE@% statement identifies the executable file, JUSTLIB1.DLL, as
  19103.       a dynamic-link library. DLLs linked with the LLIBCDLL library must
  19104.       specify %@AB@%INITINSTANCE%@AE@% in the initialization field. You could add an
  19105.       %@AB@%EXPORTS%@AE@% statement for the %@AB@%RightJustify%@AE@% function in JUSTIFY.C, but it
  19106.       is optional since the %@AB@%_export%@AE@% keyword was used in the source code.%@NL@%
  19107. %@NL@%
  19108. %@STUB@%      See Chapter 14, "Building OS/2 Applications," for more information
  19109.       about module-definition files.%@NL@%
  19110. %@NL@%
  19111.   ■   Link with LLIBCDLL.LIB.%@NL@%
  19112. %@NL@%
  19113. %@STUB@%      Ensure that the file LLIBCDLL.LIB, which takes the place of the
  19114.       regular C run-time library, is available.%@NL@%
  19115. %@NL@%
  19116. %@STUB@%      Create JUSTLIB1.DLL with a command such as%@NL@%
  19117. %@NL@%
  19118. %@AS@%      LINK justify,justlib1.dll,,,justlib1.def/NOI%@AE@%%@NL@%
  19119. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19120. %@AU@%WARNING%@AE@%%@NL@%
  19121. %@NL@%
  19122. When you link with LLIBCDLL, you cannot have any other C run-time libraries
  19123. in the link.%@NL@%
  19124. ────────────────────────────────────────────────────────────────────────────%@NL@%
  19125. %@NL@%
  19126. %@NL@%
  19127.   ■   Create an import library.%@NL@%
  19128. %@NL@%
  19129. %@STUB@%      Applications that call DLLs use import libraries to identify DLL
  19130.       functions to the linker. The following example uses JUSTLIB1.DLL and
  19131.       the IMPLIB utility to create an import library named JUSTLIB1.LIB.%@NL@%
  19132. %@NL@%
  19133. %@AS@%      IMPLIB justlib1.lib justlib1.dll%@AE@%%@NL@%
  19134. %@NL@%
  19135. %@STUB@%      For more information about import libraries, see Chapter 14, "Building
  19136.       OS/2 Applications."%@NL@%
  19137. %@NL@%
  19138. %@NL@%
  19139. %@NL@%
  19140. %@4@%%@AB@%Building Programs that Call the DLL%@AE@%%@EH@%%@NL@%
  19141. %@NL@%
  19142. To link a dynamic-link library with an application, you must have one of the
  19143. following:  %@NL@%
  19144. %@NL@%
  19145. %@NL@%
  19146.   ■   A module-definition file with an %@AB@%IMPORTS%@AE@% statement for each DLL
  19147.       function called by your program%@NL@%
  19148. %@NL@%
  19149.   ■   An import library created from the DLL itself or from a
  19150.       module-definition file%@NL@%
  19151. %@NL@%
  19152. %@NL@%
  19153. All calls to DLLs must be far calls; all pointers passed must be far data
  19154. pointers. If you do not compile with the large memory model option (/AL),
  19155. you must cast the DLL function calls and pointers yourself.  %@NL@%
  19156. %@NL@%
  19157. The sample file below, TESTJUST.C, is compiled and linked into a small-model
  19158. program named SAMPLE1.EXE. TESTJUST.C includes a function prototype that
  19159. declares %@AB@%RightJustify%@AE@% as a far function expecting a far pointer as its first
  19160. argument. Because of the prototype, the compiler will generate a far call to
  19161. %@AB@%RightJustify%@AE@% and coerce the pointer argument to the proper value.  %@NL@%
  19162. %@NL@%
  19163. %@AS@%  /* TESTJUST.C. Call sample DLL library */%@AE@%%@NL@%
  19164. %@NL@%
  19165. %@AS@%  #include <stdio.h>
  19166. %@AS@%  #include <string.h>%@AE@%%@NL@%
  19167. %@NL@%
  19168. %@AS@%  /* DLL function prototype */
  19169. %@AS@%  
  19170. %@AS@%  int _far RightJustify( char _far *, int, char );
  19171. %@AS@%  
  19172. %@AS@%  void main( void )
  19173. %@AS@%  {
  19174. %@AS@%      char buff[12];
  19175. %@AS@%  
  19176. %@AS@%      strcpy( buff, "ABCD" );
  19177. %@AS@%  
  19178. %@AS@%      /* Right justify to 8 characters and zero fill. */
  19179. %@AS@%      RightJustify( buff, 8, '0' );
  19180. %@AS@%      printf( "Result: %s\n", buff );
  19181. %@AS@%  }%@AE@%%@NL@%
  19182. %@NL@%
  19183. You need several files to link an application with a stand-alone DLL:  %@NL@%
  19184. %@NL@%
  19185. %@AB@%File Name%@AE@%                         %@AB@%Description%@AE@%
  19186. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19187. %@AI@%userdll%@AE@%.LIB                       Import library file for the DLL
  19188.  
  19189. %@AI@%userapp%@AE@%.DEF                       Optional module-definition file for your
  19190.                                   application that contains an %@AB@%IMPORTS%@AE@% 
  19191.                                   statement for each DLL function called 
  19192.                                   (required if not using an import
  19193.                                   library)
  19194.  
  19195. OS2.LIB                           Optional import library file for the 
  19196.                                   OS/2 kernel (required if your 
  19197.                                   application calls the kernel directly or
  19198.                                   via a C run-time library function)
  19199.  
  19200. %@AI@%userapp%@AE@%.OBJ                       Object module(s) for your application
  19201.  
  19202. %@AI@%m%@AE@%LIBC %@AI@%f%@AE@% P.LIB                     Regular C run-time library for protected
  19203.                                   mode, where %@AI@%m%@AE@% indicates memory model (S,
  19204.                                   C, M, L) and%@AI@%%@AE@%
  19205.                                   %@AI@%f%@AE@% indicates math package (A, E, 7)
  19206.  
  19207. The following command lines illustrate how TESTJUST.C can be compiled  and
  19208. linked with the standard libraries, plus the sample dynamic-link library,
  19209. JUSTLIB1.DLL. The example uses the small memory model library and the
  19210. JUSTLIB1.LIB import library created from JUSTLIB1.DLL to create SAMPLE1.EXE.
  19211. %@NL@%
  19212. %@NL@%
  19213. %@AS@%  CL /AS /G2 /c TESTJUST.C
  19214. %@AS@%  LINK TESTJUST,SAMPLE1.EXE,,JUSTLIB1;%@AE@%%@NL@%
  19215. %@NL@%
  19216. Make sure that the JUSTLIB1.DLL file is in a directory on your LIBPATH
  19217. before executing SAMPLE1.EXE.  %@NL@%
  19218. %@NL@%
  19219. %@NL@%
  19220. %@3@%%@CR:C6A00160016 @%%@AB@%16.3.2  DLLs without C Run-Time Library Functions%@AE@%%@EH@%%@NL@%
  19221. %@NL@%
  19222. Building a DLL that does not call any of the C run-time library functions is
  19223. similar to creating a stand-alone DLL.  %@NL@%
  19224. %@NL@%
  19225. To use the JUSTIFY.C sample program shown in Section 16.3.1, "DLLs with
  19226. Static C Run-Time Library Functions," without calling C run-time functions,
  19227. one change must be made. You must remove the call to the C run-time library
  19228. function %@AB@%strlen%@AE@%. The %@AB@%strlen%@AE@% function was used in the sample program to
  19229. calculate a pointer to the end of the caller's buffer. Remove the following
  19230. line in the program JUSTIFY.C:  %@NL@%
  19231. %@NL@%
  19232. %@AS@%  s = TargetBuff + strlen( TargetBuff ); %@AE@%%@NL@%
  19233. %@NL@%
  19234. Replace the line above with the following code fragment, which does the same
  19235. thing without calling %@AB@%strlen%@AE@%:  %@NL@%
  19236. %@NL@%
  19237. %@AS@%  s = TargetBuff;
  19238. %@AS@%  while ( *s )
  19239. %@AS@%     s++;%@AE@%%@NL@%
  19240. %@NL@%
  19241. After making this change, you can use the following commands to create a DLL
  19242. named JUSTLIB2.DLL and its import library:  %@NL@%
  19243. %@NL@%
  19244. %@AS@%  CL /c /ALw /G2s /Zl JUSTIFY.C
  19245. %@AS@%  LINK JUSTIFY,JUSTLIB2.DLL,,,JUSTLIB2.DEF/NOI
  19246. %@AS@%  IMPLIB JUSTLIB2.LIB JUSTLIB2.DLL%@AE@%%@NL@%
  19247. %@NL@%
  19248. Note that object modules compiled with releases of Microsoft C prior to
  19249. Version 6.0 refer to the C run-time library variable %@AB@%_acrtused%@AE@%. C 6.0
  19250. defines this variable if the %@AB@%main%@AE@% function is present. This causes the
  19251. linker to automatically add the C run-time start-up module to the DLL. To
  19252. suppress the start-up module, your source file must include a line defining
  19253. %@AB@%_acrtused%@AE@% as follows:  %@NL@%
  19254. %@NL@%
  19255. %@AS@%  int _acrtused = 0;%@AE@%%@NL@%
  19256. %@NL@%
  19257. This is required only if you do not use a C run-time library and if the link
  19258. includes object modules built with earlier versions of the compiler.  %@NL@%
  19259. %@NL@%
  19260. %@NL@%
  19261. %@3@%%@CR:C6A00160017 @%%@AB@%16.3.3  Programs and DLLs with a C Run-Time DLL%@AE@%%@EH@%%@NL@%
  19262. %@NL@%
  19263. The CDLLOBJS.LIB and CDLLOBJS.DEF files are the foundation for building a
  19264. DLL that consists only of C run-time library functions. The application
  19265. programs and optional dynamic-link libraries linked with this DLL do not
  19266. contain any C run-time library code.  %@NL@%
  19267. %@NL@%
  19268. You create an application to use the C run-time DLL in either two or three
  19269. phases, depending on whether or not the application has additional DLLs:  %@NL@%
  19270. %@NL@%
  19271. %@NL@%
  19272.   ■   Build a C run-time DLL.%@NL@%
  19273. %@NL@%
  19274.   ■   Build any optional DLLs that use the C run-time DLL.%@NL@%
  19275. %@NL@%
  19276.   ■   Compile and link the application.%@NL@%
  19277. %@NL@%
  19278. %@NL@%
  19279. The examples in this section use the JUSTIFY.C and TESTJUST.C source files
  19280. shown in Section 16.3.1, "DLLs with Static C Run-Time Library Functions."  %@NL@%
  19281. %@NL@%
  19282. %@NL@%
  19283. %@4@%%@AB@%Building a C Run-Time DLL%@AE@%%@EH@%%@NL@%
  19284. %@NL@%
  19285. The C run-time DLL is derived from the CDLLOBJS.LIB and CDLLOBJS.DEF files
  19286. provided with the Microsoft C Professional Development System. The
  19287. CDLLOBJS.DEF file includes export definitions for all of the C run-time
  19288. library functions.  %@NL@%
  19289. %@NL@%
  19290. The steps for creating a C run-time DLL are given below. The C run-time DLL
  19291. in the example is named CEXAMPLE.DLL.  %@NL@%
  19292. %@NL@%
  19293. %@NL@%
  19294.   1.  Create a module-definition file.%@NL@%
  19295. %@NL@%
  19296. %@STUB@%      You can use CDLLOBJS.DEF as the basis for your own module-definition
  19297.       file by copying and editing it. This allows you to create a customized
  19298.       DLL that contains only the functions your application requires. If you
  19299.       use the CDLLOBJS.DEF file without modification, every program that
  19300.       links to your C run-time DLL will get the entire C run-time library.%@NL@%
  19301. %@NL@%
  19302. %@STUB@%      The following examples create the sample file CEXAMPLE.DEF to define
  19303.       the custom dynamic link library CEXAMPLE.DLL. The CEXAMPLE.DEF file,
  19304.       shown below, exports the three C run-time library functions called
  19305.       from JUSTIFY.C and TESTJUST.C. It also exports functions required by
  19306.       the C run-time library start-up modules.%@NL@%
  19307. %@NL@%
  19308. %@AS@%      LIBRARY CEXAMPLE INITINSTANCE
  19309. %@AS@%      DESCRIPTION 'Sample Dynamic-link C Run-Time Library'
  19310. %@AS@%      DATA MULTIPLE
  19311. %@AS@%      PROTMODE
  19312. %@AS@%      EXPORTS
  19313. %@AS@%             _printf
  19314. %@AS@%             _strlen
  19315. %@AS@%             _strcpy
  19316. %@AS@%             __CRT_INIT
  19317. %@AS@%             __aFchkstk
  19318. %@AS@%             _exit%@AE@%%@NL@%
  19319. %@NL@%
  19320.   2.  Create the C run-time DLL.%@NL@%
  19321. %@NL@%
  19322. %@STUB@%      The files for creating a C run-time DLL are listed below:%@NL@%
  19323. %@NL@%
  19324. %@AB@%File Name%@AE@%                         %@AB@%Description%@AE@%
  19325. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19326. %@NL@%
  19327. OS2.LIB                           Import library for the OS/2 kernel
  19328.  
  19329. CDLLOBJS.LIB                      Dynamic link C run-time library
  19330.  
  19331. CRTLIB.OBJ                        Start-up code for C run-time DLL
  19332.  
  19333. %@AI@%yourclib%@AE@%.DEF                      Module-definition file specifying C 
  19334.                                   run-time library functions for the DLL
  19335.  
  19336. The command to create the sample CEXAMPLE.DLL file is%@NL@%
  19337. %@NL@%
  19338. %@AS@%      
  19339. %@AS@%      LINK /NOD /NOE /NOI crtlib.obj,cexample.dll,,cdllobjs+os2,cexample.def%@AE@%%@NL@%
  19340. %@NL@%
  19341.   3.  Create an import library.%@NL@%
  19342. %@NL@%
  19343. %@STUB@%      You need to create a library file of import definitions that can be
  19344.       used by programs that will be linked with your custom DLL. This is a
  19345.       two-step process. The first phase uses the module-definition file and
  19346.       the IMPLIB utility to create an interim version of the library, as in
  19347.       this example:%@NL@%
  19348. %@NL@%
  19349. %@AS@%      IMPLIB cexample.lib cexample.def%@AE@%%@NL@%
  19350. %@NL@%
  19351. %@STUB@%      Note that the IMPLIB utility accepts either a module-definition file
  19352.       or a DLL as input.%@NL@%
  19353. %@NL@%
  19354. %@STUB@%      The second step uses the LIB utility to append the file CDLLSUPP.LIB
  19355.       to the import library. You must append CDLLSUPP.LIB because it
  19356.       contains some routines that cannot be dynamically linked. The LIB
  19357.       utility requires the full path name for CDLLSUPP.LIB. If it is in a
  19358.       directory named C:\ LIB, the command to complete the library build for
  19359.       CEXAMPLE.LIB is%@NL@%
  19360. %@NL@%
  19361. %@AS@%      LIB CEXAMPLE.LIB+C:\LIB\CDLLSUPP.LIB;%@AE@%%@NL@%
  19362. %@NL@%
  19363. %@STUB@%      When you have finished building the custom DLL, be sure to copy it to
  19364.       a directory specified in the %@AB@%LIBPATH%@AE@% statement of the CONFIG.SYS file.%@NL@%
  19365. %@NL@%
  19366. %@NL@%
  19367. %@NL@%
  19368. %@4@%%@AB@%Building an Application-Specific DLL%@AE@%%@EH@%%@NL@%
  19369. %@NL@%
  19370. You must compile a DLL that calls a C run-time DLL with specific options
  19371. and link it with the C run-time DLL's import library. The steps for building
  19372. an application-specific DLL named JUSTLIB3.DLL are given below.  %@NL@%
  19373. %@NL@%
  19374. %@NL@%
  19375.   1.  Compile with the /MD option.%@NL@%
  19376. %@NL@%
  19377. %@STUB@%      The easiest way to be sure you choose the proper options is to use the
  19378.       /MD switch, which indicates that the DLL will be used with a C
  19379.       run-time DLL. When you use /MD, library search records are suppressed
  19380.       and the following options are in effect:%@NL@%
  19381. %@NL@%
  19382. %@AB@%Option%@AE@%                            %@AB@%Effect%@AE@%
  19383. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19384. %@NL@%
  19385. /ALw                              Use large memory model with separate 
  19386.                                   stack
  19387.                                   segment
  19388.  
  19389. /G2                               Use 80286 processor instruction set
  19390.  
  19391. /D MT                             Use the multithread version of the 
  19392.                                   include files
  19393.  
  19394. /D DLL                            Use a C run-time dynamic-link library
  19395.  
  19396. /FPi                              Generate in-line floating-point 
  19397.                                   instructions and select the emulator 
  19398.                                   math package
  19399.  
  19400. The /G2 and /ALw options can be overridden. The FPi option can be replaced
  19401. with /FPi87 or /FPc, but not with /FPa. See Chapter 4, "Controlling
  19402. Floating-Point Math Operations," for more information about compatible
  19403. floating-point options.%@NL@%
  19404. %@NL@%
  19405. %@STUB@%      You should also use the /c option to compile without linking. The
  19406.       command line to compile the sample file JUSTIFY.C is%@NL@%
  19407. %@NL@%
  19408. %@AS@%      CL /MD /c JUSTIFY.C%@AE@%%@NL@%
  19409. %@NL@%
  19410.   2.  Create a module-definition file.%@NL@%
  19411. %@NL@%
  19412. %@STUB@%      Create a module-definition file named JUSTLIB3.DEF that includes the
  19413.       following line:%@NL@%
  19414. %@NL@%
  19415. %@AS@%      LIBRARY JUSTLIB3 INITINSTANCE%@AE@%%@NL@%
  19416. %@NL@%
  19417.   3.  Link the DLL with the C run-time and OS/2 import libraries.%@NL@%
  19418. %@NL@%
  19419. %@STUB@%      To create a DLL that will call a C run-time DLL, the following files
  19420.       must be linked together:%@NL@%
  19421. %@NL@%
  19422. %@AB@%File Name%@AE@%                         %@AB@%Description%@AE@%
  19423. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19424. %@NL@%
  19425. OS2.LIB                           Import library for the OS/2 kernel
  19426.  
  19427. %@AI@%yourclib%@AE@%.LIB                      Import library for your C run-time DLL
  19428.  
  19429. CRTDLL.OBJ                        Start-up code for DLLs using a C 
  19430.                                   run-time DLL
  19431.  
  19432. CRTDLL_I.OBJ                      Optional initialization module for DLLs 
  19433.                                   requiring custom initialization 
  19434.                                   (replaces CRTDLL.OBJ)
  19435.  
  19436. %@AI@%yourdll%@AE@%.OBJ                       Object file for your DLL
  19437.  
  19438. %@AI@%yourdll%@AE@%.DEF                       Module-definition file for your DLL
  19439.  
  19440. The command for linking these files to create JUSTLIB3.DLL is%@NL@%
  19441. %@NL@%
  19442. %@AS@%      
  19443. %@AS@%      LINK justify+crtdll,justlib3.dll,,cexample+os2,justlib3.def%@AE@%%@NL@%
  19444. %@NL@%
  19445.   4.  Create an import library.%@NL@%
  19446. %@NL@%
  19447. %@STUB@%      Use JUSTLIB3.DLL and the IMPLIB utility to create an import library
  19448.       file, JUSTLIB3.LIB, for use by applications calling JUSTLIB3.DLL:%@NL@%
  19449. %@NL@%
  19450. %@AS@%      IMPLIB JUSTLIB3.LIB JUSTLIB3.DLL%@AE@%%@NL@%
  19451. %@NL@%
  19452. %@STUB@%      Remember to copy JUSTLIB3.DLL to a directory named in the %@AB@%LIBPATH%@AE@%
  19453.       statement in the CONFIG.SYS file.%@NL@%
  19454. %@NL@%
  19455. %@NL@%
  19456. %@NL@%
  19457. %@4@%%@AB@%Using C Run-Time and Application-Specific DLLs%@AE@%%@EH@%%@NL@%
  19458. %@NL@%
  19459. Application programs using a C run-time DLL, such as the sample program
  19460. CEXAMPLE.DLL (described earilier in this section), must define the symbolic
  19461. constants %@AB@%MT%@AE@% and %@AB@%DLL%@AE@%. These constants cause the compiler to use the
  19462. multithread and DLL sections of the include files. You can define the
  19463. constants in your source code or with the compiler's /D command-line option.
  19464. Since the C run-time DLL uses the large memory model, your program must
  19465. either use the same model or declare all C run-time functions and pointers
  19466. passed to them as %@AB@%_far%@AE@%. If you use the standard include files for the C
  19467. run-time functions in your program, all these declarations are made for you.
  19468. %@NL@%
  19469. %@NL@%
  19470. The following files are required to link an application that calls a C
  19471. runtime DLL:  %@NL@%
  19472. %@NL@%
  19473. %@AB@%File Name%@AE@%                         %@AB@%Description%@AE@%
  19474. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19475. OS2.LIB                           Import library for the OS/2 kernel
  19476.  
  19477. %@AI@%yourclib%@AE@%.LIB                      Import library for your C run-time DLL
  19478.  
  19479. %@AI@%yourdll%@AE@%.LIB                       Import library for each optional 
  19480.                                   application DLL
  19481.  
  19482. CRTEXE.OBJ                        Start-up code for executable files 
  19483.                                   calling a C run-time DLL
  19484.  
  19485. %@AI@%yourapp%@AE@%.OBJ                       Object file(s) for your application
  19486.  
  19487. %@AI@%yourapp%@AE@%.DEF                       Optional module-definition file for your
  19488.                                   application
  19489.  
  19490. The following commands compile and link the TESTJUST.C file from Section
  19491. 16.3.1 for use with the dynamic-link libraries CEXAMPLE.DLL and
  19492. JUSTLIB3.DLL. The link command uses the /NOD option to suppress selection of
  19493. the standard large-model library. The result is a program named SAMPLE2.EXE.
  19494. %@NL@%
  19495. %@NL@%
  19496. %@AS@%  CL /AL /D MT /D DLL /G2 /c TESTJUST.C
  19497. %@AS@%  LINK /NOD TESTJUST+CRTEXE,SAMPLE2.EXE,,CEXAMPLE+OS2+JUSTLIB3;%@AE@%%@NL@%
  19498. %@NL@%
  19499. %@NL@%
  19500. %@3@%%@CR:C6A00160018 @%%@AB@%16.3.4  Using CodeView to Debug Dynamic-Link Libraries%@AE@%%@EH@%%@NL@%
  19501. %@NL@%
  19502. The protected-mode version of CodeView (CVP) supports debugging of
  19503. dynamic-link libraries. The /L option lets you name one or more DLLs to be
  19504. debugged with your application.  %@NL@%
  19505. %@NL@%
  19506. To enable full symbolic debugging, use the CodeView options /Zi when
  19507. compiling and /CO when linking. Do this for both the DLL to be debugged and
  19508. for the program that calls the DLL.  %@NL@%
  19509. %@NL@%
  19510. The syntax for the /L CodeView option is  %@NL@%
  19511. %@NL@%
  19512. %@AS@%  /L file%@AE@%%@NL@%
  19513. %@NL@%
  19514. At least one space must separate /L from the file name(s). You can enter
  19515. multiple DLL names. To debug the JUSTLIB3.DLL dynamic-link library and the
  19516. SAMPLE2.EXE program discussed in the previous section, use this command
  19517. line:%@CR:C6A00160019 @%  %@NL@%
  19518. %@NL@%
  19519. %@AS@%  CVP /L JUSTLIB3.DLL SAMPLE2.EXE%@AE@%%@NL@%
  19520. %@NL@%
  19521. %@AU@% Use the CodeView Trace com%@AE@%%@AB@%mand (F8) to enter an%@AE@%d view DLL code.  %@NL@%
  19522. %@NL@%
  19523. A simple way to use CodeView is to place a breakpoint at the instruction
  19524. that calls the DLL function you want to debug. When you reach the
  19525. breakpoint, press F8 to execute the current source line. CodeView will then
  19526. display the DLL function's source code, allowing you to set additional
  19527. breakpoints and enter other CodeView commands.  %@NL@%
  19528. %@NL@%
  19529. %@NL@%
  19530. %@NL@%
  19531. %@NL@%
  19532. %@NL@%
  19533. %@NL@%
  19534. %@CR:C6A-A0001   @%%@1@%%@AB@%Appendix A  Using Exit Codes%@AE@%%@EH@%%@NL@%
  19535. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19536. %@NL@%
  19537. When C programs terminate, they return values to the process that started
  19538. them. These values are called "exit codes." The process that starts a C
  19539. program can be either an operating system, such as DOS or OS/2, or another
  19540. program. The process that starts the C program is referred to as the "parent
  19541. process"; the program started is referred to as the "child process." The
  19542. parent process can interpret return values as an error code sent to the
  19543. operating system or use those return values as a form of interprocess
  19544. communication (communication between two separate processes).%@CR:C6A-A0002   @%  %@NL@%
  19545. %@NL@%
  19546. %@NL@%
  19547. %@2@%%@CR:C6A-A0003   @%%@AB@%A.1  The exit Function%@AE@%%@EH@%%@NL@%
  19548. %@NL@%
  19549. The %@AB@%exit%@AE@% function terminates execution of your C program and returns an exit
  19550. code (an integer value) to the parent process. The parent process can be the
  19551. operating system or another program, depending on how the child process was
  19552. executed. Note that a C program always returns an integer, regardless of how
  19553. you declare the %@AB@%main%@AE@% function.  %@NL@%
  19554. %@NL@%
  19555. Most programs use exit codes to communicate errors to the parent process;
  19556. these are called "error codes." By convention, programs return zero if they
  19557. complete normally and a nonzero value if they are exiting because of an
  19558. error. This error code (the nonzero value) can then be used by the operating
  19559. system to control the execution of other programs (for example, from inside
  19560. a batch file).  %@NL@%
  19561. %@NL@%
  19562. The Microsoft C compiler is a good example of a program that returns an exit
  19563. code. It returns 0 if no errors occur in your compile and a positive value
  19564. if an error occurs during compilation.  %@NL@%
  19565. %@NL@%
  19566. The following program attempts to open a file for reading. If the file
  19567. cannot be opened, %@AB@%exit%@AE@% returns 1 to the calling program. Therefore, 1 and 0
  19568. are both exit codes.  %@NL@%
  19569. %@NL@%
  19570. %@AS@%  #include <stdio.h>
  19571. %@AS@%  
  19572. %@AS@%  int main(void)
  19573. %@AS@%  {
  19574. %@AS@%     FILE * fp;
  19575. %@AS@%  
  19576. %@AS@%     if( !(fp = fopen( filename, "rb" )) )
  19577. %@AS@%     {
  19578. %@AS@%         printf("Error %d: Could not open file\n", errno);
  19579. %@AS@%         exit(1);
  19580. %@AS@%     }
  19581. %@AS@%  
  19582. %@AS@%     do_file_access(fp);
  19583. %@AS@%  }%@AE@%%@NL@%
  19584. %@NL@%
  19585. In the preceding example, the exit code is unpredictable because the %@AB@%exit
  19586. %@AB@%%@AE@%function is not used. The value actually returned to the parent process (or
  19587. to the operating system shell) is whatever happens to be in the AX register
  19588. when the program terminates─in this case, whatever %@AS@% do_file_access %@AE@%
  19589. returned.  %@NL@%
  19590. %@NL@%
  19591. %@NL@%
  19592. %@2@%%@CR:C6A-A0004   @%%@AB@%A.2  Testing Exit Codes from Command and Batch Files%@AE@%%@EH@%%@NL@%
  19593. %@NL@%
  19594. Using the IF ERRORLEVEL command, you can test to see if a program has
  19595. executed successfully by checking its exit code. The IF ERRORLEVEL command
  19596. is an OS/2 command file or DOS batch file command that tests the exit code
  19597. of the most recently executed program.  %@NL@%
  19598. %@NL@%
  19599. IF ERRORLEVEL can help you organize program execution. For example, you can
  19600. define program execution to be dependent on the successful exit code testing
  19601. of earlier programs by IF ERRORLEVEL. You can also use the value of the exit
  19602. code to branch to different commands in a batch or command file.  %@NL@%
  19603. %@NL@%
  19604. When placed in a batch or command file, the following commands will execute
  19605. REPORTS.EXE only if FILEMNG.EXE does not return an error:  %@NL@%
  19606. %@NL@%
  19607. %@AS@%  echo Running file manager....
  19608. %@AS@%  FILEMNG.EXE
  19609. %@AS@%  IF NOT ERRORLEVEL 1 REPORTS.EXE%@AE@%%@NL@%
  19610. %@NL@%
  19611. Despite the name %@AS@% ERRORLEVEL%@AE@%, the exit code does not always denote an error.
  19612. You can define error codes to communicate any information useful to you.  %@NL@%
  19613. %@NL@%
  19614. Refer to the %@AI@%Microsoft Operating System/2 User's Guide%@AE@% or the %@AI@%Microsoft
  19615. %@AI@%MS-DOS User's Guide and User's Reference %@AE@%for more information about the IF
  19616. ERRORLEVEL command.  %@NL@%
  19617. %@NL@%
  19618. %@NL@%
  19619. %@2@%%@CR:C6A-A0005   @%%@AB@%A.3  Accessing Exit Codes from Other Programs%@AE@%%@EH@%%@NL@%
  19620. %@NL@%
  19621. When you use any of the %@AB@%spawn%@AE@% family of functions to run a program as the
  19622. child of another program, the return value of %@AB@%spawn %@AE@%is the exit code of the
  19623. function. The following code performs the same function as the batch file in
  19624. Section A.2:  %@NL@%
  19625. %@NL@%
  19626. %@AS@%  void main( void )
  19627. %@AS@%  {
  19628. %@AS@%     if( !spawnl( P_WAIT, "filemng.exe", "filemng.exe", 
  19629. %@AS@%                   NULL ) )
  19630. %@AS@%         spawnl( P_WAIT, "reports.exe", "reports.exe", 
  19631. %@AS@%                  NULL );
  19632. %@AS@%  }%@AE@%%@NL@%
  19633. %@NL@%
  19634. The program %@AS@% reports.exe %@AE@% is executed only if the program %@AS@% filemng.exe
  19635. %@AS@%%@AE@%terminates with an exit code of 0.  %@NL@%
  19636. %@NL@%
  19637. The following code uses the exit code as part of a simple menu system:  %@NL@%
  19638. %@NL@%
  19639. %@AS@%  void main(void)
  19640. %@AS@%  {
  19641. %@AS@%     int option;
  19642. %@AS@%     int menu_num = 0;  /* Initialize for first execution */
  19643. %@AS@%  
  19644. %@AS@%     while( (option = spawnl( P_WAIT, "menu.exe",
  19645. %@AS@%                          "menu.exe", menu_num, NULL )) )
  19646. %@AS@%      {
  19647. %@AS@%          switch( option )
  19648. %@AS@%          {
  19649. %@AS@%              case 1 :
  19650. %@AS@%                  menu_num = spawnl( P_WAIT, "program1.exe",
  19651. %@AS@%                                "program1.exe", NULL );
  19652. %@AS@%                  break;
  19653. %@AS@%              case 2 :
  19654. %@AS@%                  menu_num = spawnl( P_WAIT, "program2.exe",
  19655. %@AS@%                                 "program2.exe", NULL );
  19656. %@AS@%                  break;
  19657. %@AS@%              case 3 :
  19658. %@AS@%                  menu_num = spawnl( P_WAIT, "program3.exe",
  19659. %@AS@%                                 "program3.exe", NULL );
  19660. %@AS@%                 break;
  19661. %@AS@%             default:       /* Guard against a bad option */
  19662. %@AS@%                 break;
  19663. %@AS@%         }
  19664. %@AS@%      }
  19665. %@AS@%  }%@AE@%%@NL@%
  19666. %@NL@%
  19667. The preceding example demonstrates how you could have a program, %@AS@% menu.exe%@AE@%,
  19668. that solicits input from a menu of choices. This input is interpreted and
  19669. passed back to the main program in the form of an exit code. (The %@AB@%spawnl%@AE@%
  19670. function returns the value of the child process's exit code.) This exit code
  19671. value is stored in %@AS@% option%@AE@%, which is used as a selector variable in a switch
  19672. statement.  %@NL@%
  19673. %@NL@%
  19674. Based on the value returned from %@AS@% menu.exe%@AE@%, the main program executes
  19675. %@AS@%program1.exe%@AE@%, %@AS@% program2.exe%@AE@%, or %@AS@% program3.exe%@AE@%. Finally, %@AS@% menu_num%@AE@%, the exit
  19676. code of the program selected, is used as a parameter to the next execution
  19677. of %@AS@% menu.exe%@AE@%.  %@NL@%
  19678. %@NL@%
  19679. %@NL@%
  19680. %@NL@%
  19681. %@NL@%
  19682. %@NL@%
  19683. %@NL@%
  19684. %@CR:C6A-B0001   @%%@1@%%@AB@%Appendix B  Differences between C Versions 5.1 and 6.0%@AE@%%@EH@%%@NL@%
  19685. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19686. %@NL@%
  19687. This appendix describes the differences between versions 5.1 and 6.0 of
  19688. Microsoft C, including additions, deletions, and changes. Some of the
  19689. changes are required by the American National Standards Institute (ANSI)
  19690. draft standard for the C programming language. Other changes improve or
  19691. augment the existing capabilities of the compiler.  %@NL@%
  19692. %@NL@%
  19693. Many of the changes will have no effect on code that was written and
  19694. compiled with previous versions of Microsoft C. In some cases, however, you
  19695. may have to modify or correct existing code before compiling with version
  19696. 6.0.  %@NL@%
  19697. %@NL@%
  19698. %@NL@%
  19699. %@2@%%@CR:C6A-B0002   @%%@AB@%B.1  Modifications for ANSI Compatibility%@AE@%%@EH@%%@NL@%
  19700. %@NL@%
  19701. A number of changes have been made to the compiler to support the ANSI draft
  19702. standard. These include new features (Section B.1.1) and changes (Sections
  19703. B.1.2 - B.1.8).  %@NL@%
  19704. %@NL@%
  19705. %@NL@%
  19706. %@3@%%@CR:C6A-B0003   @%%@AB@%B.1.1  ANSI-Mandated New Features%@AE@%%@EH@%%@NL@%
  19707. %@NL@%
  19708. The following ANSI-mandated features are new to version 6.0:  %@NL@%
  19709. %@NL@%
  19710. %@NL@%
  19711.   ■   The semantics for %@AB@%volatile%@AE@% have been implemented.%@NL@%
  19712. %@NL@%
  19713.   ■   Both %@AB@%long %@AE@%and %@AB@%unsigned long%@AE@% values are allowed in switch expressions
  19714.       and case constants.%@NL@%
  19715. %@NL@%
  19716.   ■   The compiler supports %@AB@%unsigned long%@AE@% decimal constants. It is now
  19717.       possible to initialize %@AB@%unsigned long%@AE@% variables with values larger than
  19718.       %@AB@%MAX_LONG%@AE@% using decimal (rather than hexadecimal or octal) constants.%@NL@%
  19719. %@NL@%
  19720.   ■   Bit fields are permitted in unions.%@NL@%
  19721. %@NL@%
  19722.   ■   The address-of operator (%@AB@%&%@AE@%) works correctly on arrays and functions.%@NL@%
  19723. %@NL@%
  19724.   ■   Storage classes or types (or both) are now required on variable
  19725.       declarations. The compiler previously assumed that untyped variables
  19726.       (such as %@AS@% a;%@AE@%) were integers. This declaration now generates a warning.%@NL@%
  19727. %@NL@%
  19728.   ■   The LOCALE.H header file is new to version 6.0. It declares functions
  19729.       and structures for describing conventions that vary from one country
  19730.       to the next, such as the currency symbol and the way calendar dates
  19731.       are printed.%@NL@%
  19732. %@NL@%
  19733. %@NL@%
  19734. %@NL@%
  19735. %@3@%%@CR:C6A-B0004   @%%@AB@%B.1.2  Integer Promotion Rules%@AE@%%@EH@%%@NL@%
  19736. %@NL@%
  19737. The ANSI draft standard requires a change in the evaluation of some
  19738. expressions that mix signed and unsigned integers. Earlier versions of the
  19739. compiler attempted to preserve an expression's unsigned nature as much as
  19740. possible. Version 6.0 attempts to preserve the expression's value.  %@NL@%
  19741. %@NL@%
  19742. In version 5.1, an %@AB@%unsigned char%@AE@% promotes to an %@AB@%unsigned int%@AE@%; an %@AB@%unsigned
  19743. %@AB@%int%@AE@% promotes to an %@AB@%unsigned long%@AE@%.  %@NL@%
  19744. %@NL@%
  19745. In version 6.0, an %@AB@%unsigned char%@AE@% promotes to a %@AB@%signed int%@AE@%; an %@AB@%unsigned int%@AE@%
  19746. promotes to a %@AB@%signed long%@AE@%.  %@NL@%
  19747. %@NL@%
  19748. For example,  %@NL@%
  19749. %@NL@%
  19750. %@AS@%  main()
  19751. %@AS@%  {
  19752. %@AS@%    long int li = -256L;
  19753. %@AS@%    test( li );
  19754. %@AS@%  }
  19755. %@AS@%  
  19756. %@AS@%  test( long li) 
  19757. %@AS@%  {
  19758. %@AS@%    if( li < 0xffff )
  19759. %@AS@%       puts( "C 6.0 does a signed compare" );
  19760. %@AS@%     else puts( "C 5.1 does an unsigned compare" );
  19761. %@AS@%  }%@AE@%%@NL@%
  19762. %@NL@%
  19763. %@NL@%
  19764. %@3@%%@CR:C6A-B0005   @%%@AB@%B.1.3  Defining NULL as a Pointer%@AE@%%@EH@%%@NL@%
  19765. %@NL@%
  19766. The constant %@AB@%NULL %@AE@%is now defined as %@AS@% ((void *)0)%@AE@%. Previous versions of
  19767. Microsoft C defined %@AB@%NULL%@AE@% as 0x0000 in small and medium models and
  19768. 0x00000000L in compact and large models.  %@NL@%
  19769. %@NL@%
  19770. %@NL@%
  19771. %@3@%%@CR:C6A-B0006   @%%@AB@%B.1.4  Shift Operators%@AE@%%@EH@%%@NL@%
  19772. %@NL@%
  19773. Shift operators now give a result that is of the same type as the left side.
  19774. For example,  %@NL@%
  19775. %@NL@%
  19776. %@AS@%  short si;
  19777. %@AS@%  long li;
  19778. %@AS@%  si = 0x0001;
  19779. %@AS@%  li = si << 16L;%@AE@%%@NL@%
  19780. %@NL@%
  19781. The compiler previously yielded a result that was the size of the largest of
  19782. the two values. In the example above, the short value would be automatically
  19783. cast to a long because 16L is long. The value assigned to %@AS@% li %@AE@% would be
  19784. 0x00010000L in Microsoft C 5.1.  %@NL@%
  19785. %@NL@%
  19786. To adhere to the ANSI draft standard, Microsoft C 6.0 maintains the size of
  19787. the left operand. The variable %@AS@% si %@AE@% has 16 bits. Shifting left 16 times
  19788. produces a value of 0, which is then assigned to %@AS@% li%@AE@%.  %@NL@%
  19789. %@NL@%
  19790. %@NL@%
  19791. %@3@%%@CR:C6A-B0007   @%%@AB@%B.1.5  Pointers to Typedefs%@AE@%%@EH@%%@NL@%
  19792. %@NL@%
  19793. The rules for handling pointers to typedefs have changed subtly. For
  19794. example, C 5.1 interprets  %@NL@%
  19795. %@NL@%
  19796. %@AS@%  typedef int far f_int;
  19797. %@AS@%  f_int *fp_i;%@AE@%%@NL@%
  19798. %@NL@%
  19799. as being equivalent to  %@NL@%
  19800. %@NL@%
  19801. %@AS@%  int *far fp_i;%@AE@%%@NL@%
  19802. %@NL@%
  19803. which means %@AS@% fp_i %@AE@% is a distant pointer to an integer. The address of %@AS@% fp_i %@AE@%
  19804. contains 32 bits. The size of the integer's address is indeterminate.  %@NL@%
  19805. %@NL@%
  19806. C 6.0 interprets it as  %@NL@%
  19807. %@NL@%
  19808. %@AS@%  int far *fp_i;%@AE@%%@NL@%
  19809. %@NL@%
  19810. This means %@AS@% fp_i %@AE@% is a far pointer to an integer. The address of the integer
  19811. contains 32 bits. The size of the address of %@AS@% fp_i %@AE@% is indeterminate. %@AS@%  %@AE@%%@NL@%
  19812. %@NL@%
  19813. This affects typedefs containing %@AB@%_near%@AE@%, %@AB@%_far%@AE@%, %@AB@%_based%@AE@%, and other modifiers.
  19814. Although these are Microsoft-specific keywords, their new behavior is
  19815. consistent with what the ANSI draft standard requires for the %@AB@%const %@AE@%and
  19816. %@AB@%volatile %@AE@%keywords.  %@NL@%
  19817. %@NL@%
  19818. %@NL@%
  19819. %@3@%%@CR:C6A-B0008   @%%@AB@%B.1.6  Identifying Nonstandard Keywords%@AE@%%@EH@%%@NL@%
  19820. %@NL@%
  19821. The following modifiers are specific to Microsoft C; they are not described
  19822. in the ANSI draft standard. To identify these implementation-defined
  19823. keywords as non-ANSI, an initial underscore has been added.%@CR:C6A-B0009   @%  %@NL@%
  19824. %@NL@%
  19825. %@AB@%C 5.1 Keyword%@AE@%                     %@AB@%C 6.0 Keyword%@AE@%
  19826. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19827. %@AB@%far%@AE@%                               %@AB@%_far%@AE@%
  19828.  
  19829. %@AB@%huge%@AE@%                              %@AB@%_huge%@AE@%
  19830.  
  19831. %@AB@%near%@AE@%                              %@AB@%_near%@AE@%
  19832.  
  19833. %@AB@%cdecl%@AE@%                             %@AB@%_cdecl%@AE@%
  19834.  
  19835. %@AB@%fortran%@AE@%                           %@AB@%_fortran%@AE@%
  19836.  
  19837. %@AB@%interrupt%@AE@%                         %@AB@%_interrupt%@AE@%
  19838.  
  19839. %@AB@%pascal%@AE@%                            %@AB@%_pascal%@AE@%
  19840.  
  19841. The compiler still accepts the obsolescent versions of these keywords,
  19842. unless the /Za option is used.  %@NL@%
  19843. %@NL@%
  19844. %@NL@%
  19845. %@3@%%@CR:C6A-B0010   @%%@AB@%B.1.7  Trigraphs%@AE@%%@EH@%%@NL@%
  19846. %@NL@%
  19847. To maintain compatibility with and portability to other systems, Microsoft C
  19848. 6.0 supports the following trigraphs:  %@NL@%
  19849. %@NL@%
  19850. %@AB@%Trigraph%@AE@%                          %@AB@%Character%@AE@%
  19851. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19852. %@AB@%??=%@AE@%                               %@AB@%#%@AE@%
  19853.  
  19854. %@AB@%??(%@AE@%                               %@AB@%[%@AE@%
  19855.  
  19856. %@AB@%??/%@AE@%                               %@AB@%\%@AE@%
  19857.  
  19858. %@AB@%??)%@AE@%                               %@AB@%]%@AE@%
  19859.  
  19860. %@AB@%??'%@AE@%                               %@AB@%^%@AE@%
  19861.  
  19862. %@AB@%??<%@AE@%                               %@AB@%{%@AE@%
  19863.  
  19864. %@AB@%??!%@AE@%                               %@AB@%|%@AE@%
  19865.  
  19866. %@AB@%??>%@AE@%                               %@AB@%}%@AE@%
  19867.  
  19868. %@AB@%??-%@AE@%                               %@AB@%~%@AE@%
  19869.  
  19870. %@NL@%
  19871. %@3@%%@CR:C6A-B0011   @%%@AB@%B.1.8  ANSI Nonconformance%@AE@%%@EH@%%@NL@%
  19872. %@NL@%
  19873. This section lists the areas where Microsoft C 6.0 does not conform to the
  19874. ANSI draft standard.  %@NL@%
  19875. %@NL@%
  19876. %@NL@%
  19877.   ■   Microsoft C does not support multibyte characters, wide-character and
  19878.       string constants, and the related library functions and types.%@NL@%
  19879. %@NL@%
  19880.   ■   Microsoft C contains some name-space violations in the language
  19881.       (extended keywords, such as %@AB@%near%@AE@% and %@AB@%far%@AE@%) and in the library (non-ANSI
  19882.       macros and types in header files and extended library function names,
  19883.       such as %@AB@%read %@AE@%and %@AB@%write%@AE@%).%@NL@%
  19884. %@NL@%
  19885. %@NL@%
  19886. %@NL@%
  19887. %@2@%%@CR:C6A-B0012   @%%@AB@%B.2  New Keywords and Functions%@AE@%%@EH@%%@NL@%
  19888. %@NL@%
  19889. This section describes keywords and functions that did not exist in previous
  19890. versions of Microsoft C. Details about how to use these features can be
  19891. found elsewhere in the documentation.  %@NL@%
  19892. %@NL@%
  19893. %@NL@%
  19894. %@3@%%@CR:C6A-B0013   @%%@AB@%B.2.1  In-Line Assembler%@AE@%%@EH@%%@NL@%
  19895. %@NL@%
  19896. The new %@AB@%_asm%@AE@% keyword allows you to mix assembly instructions with C source
  19897. code. This feature includes the %@AB@%_emit%@AE@% function, which lets you enter
  19898. arbitrary values into the code stream.  %@NL@%
  19899. %@NL@%
  19900. See Chapter 3, "Using the In-Line Assembler."  %@NL@%
  19901. %@NL@%
  19902. %@NL@%
  19903. %@3@%%@CR:C6A-B0014   @%%@AB@%B.2.2  Based Pointers and Objects%@AE@%%@EH@%%@NL@%
  19904. %@NL@%
  19905. A based pointer is a special, compact form of pointer. It is always
  19906. represented as a short offset. The address represented by such a pointer is
  19907. calculated by adding the based pointer to its base. The base must be
  19908. supplied each time the pointer is dereferenced, either explicitly using a
  19909. special operator or implicitly by associating the base value with the
  19910. pointer when it is declared. The base can be a far pointer, a near pointer,
  19911. or a new type that represents a segment.  %@NL@%
  19912. %@NL@%
  19913. Based pointers and objects are declared using the new keyword, %@AB@%_based%@AE@%.  %@NL@%
  19914. %@NL@%
  19915. %@NL@%
  19916. %@4@%%@AB@%Segment Types%@AE@%%@EH@%%@NL@%
  19917. %@NL@%
  19918. The new type specifier, %@AB@%_segment%@AE@%, specifies a segment.  %@NL@%
  19919. %@NL@%
  19920. Any pointer or address can be cast to %@AB@%_segment%@AE@%. If the operand is a near
  19921. pointer, the result is the current value of the data segment register (DS).
  19922. If the operand is a far pointer, the result is the segment part of the far
  19923. pointer.  %@NL@%
  19924. %@NL@%
  19925. %@NL@%
  19926. %@4@%%@AB@%Segment Names%@AE@%%@EH@%%@NL@%
  19927. %@NL@%
  19928. Segment names are declared using the built-in function %@AB@%_segname%@AE@%. The
  19929. compiler recognizes four predefined segment names: %@AB@%_CODE%@AE@%, %@AB@%_CONST%@AE@%, %@AB@%_DATA%@AE@%, and
  19930. %@AB@%_STACK%@AE@%.  %@NL@%
  19931. %@NL@%
  19932. Each segment name represents a constant of type %@AB@%_segment%@AE@%.  %@NL@%
  19933. %@NL@%
  19934. %@NL@%
  19935. %@4@%%@AB@%Base Operator%@AE@%%@EH@%%@NL@%
  19936. %@NL@%
  19937. The base operator%@AB@% %@AE@%(%@AB@%:>%@AE@%) associates a base expression (usually a segment) with
  19938. a based pointer, to form a far pointer value. For example,  %@NL@%
  19939. %@NL@%
  19940. %@AS@%  0x0F01:>0x0015%@AE@%%@NL@%
  19941. %@NL@%
  19942. combines the segment 0x0F01 with the offset 0x0015 to form the effective
  19943. address 0x0F025. The base operator's precedence falls between ( ) and [ ].  %@NL@%
  19944. %@NL@%
  19945. %@NL@%
  19946. %@4@%%@AB@%Casting Based Pointers%@AE@%%@EH@%%@NL@%
  19947. %@NL@%
  19948. A based pointer can be cast to a pointer, a long integer, a short integer,
  19949. or another based pointer. When a based pointer is converted to a far
  19950. pointer, a long integer, a near pointer, or another based pointer having a
  19951. different base expression, it is first normalized to a far pointer
  19952. (including adding the offset in the base, if present, to the based pointer);
  19953. then any additional conversions are applied.  %@NL@%
  19954. %@NL@%
  19955. %@NL@%
  19956. %@4@%%@AB@%Operations on Based Pointers%@AE@%%@EH@%%@NL@%
  19957. %@NL@%
  19958. Based pointers, for the purpose of arithmetic and dereferencing, are treated
  19959. as semantically equivalent to far pointers. When a based pointer mixes with
  19960. another integral type (%@AB@%int%@AE@%, %@AB@%long%@AE@%, near pointer, far pointer, or based
  19961. pointer), implicit casting is done. In some cases, the compiler can optimize
  19962. these references and treat the pointer as an offset.  %@NL@%
  19963. %@NL@%
  19964. The value of 0 is treated specially, as it is for near and far pointers. No
  19965. conversions are applied to the constant 0 because it is assumed to be a null
  19966. pointer.  %@NL@%
  19967. %@NL@%
  19968. See Chapter 2, "Managing Memory."  %@NL@%
  19969. %@NL@%
  19970. %@NL@%
  19971. %@3@%%@CR:C6A-B0015   @%%@AB@%B.2.3  Based Heap Allocation Support%@AE@%%@EH@%%@NL@%
  19972. %@NL@%
  19973. The functions listed below provide support for allocating, expanding, and
  19974. freeing memory for based heaps, which dynamically allocate memory for based
  19975. items. The functions are prototyped in the MALLOC.H include file.  %@NL@%
  19976. %@NL@%
  19977. %@TH:   6   421 01 11 12 53 @%
  19978. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19979. %@AB@%_bcalloc%@AE@%   %@AB@%_bheapchk%@AE@%   %@AB@%_bmalloc%@AE@%
  19980. %@AB@%_bexpand%@AE@%   %@AB@%_bheapmin%@AE@%   %@AB@%_bmsize%@AE@%
  19981. %@AB@%_bfree%@AE@%     %@AB@%_bheapseg%@AE@%   %@AB@%_brealloc%@AE@%
  19982. %@AB@%_bfreeseg%@AE@%  %@AB@%_bheapset%@AE@%
  19983. %@AB@%_bheapadd%@AE@%  %@AB@%_bheapwalk%@AE@%
  19984. %@TE:   6   421 01 11 12 53 @%
  19985.  
  19986. See Chapter 2, "Managing Memory."  %@NL@%
  19987. %@NL@%
  19988. %@NL@%
  19989. %@3@%%@CR:C6A-B0016   @%%@AB@%B.2.4  Releasing Unused Heap Memory%@AE@%%@EH@%%@NL@%
  19990. %@NL@%
  19991. The following routines release unused heap memory by shortening data
  19992. segments. MALLOC.H contains the function prototypes.  %@NL@%
  19993. %@NL@%
  19994. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19995. %@AB@%_fheapmin%@AE@%                                                                   
  19996. %@AB@%_heapmin%@AE@%                                                                    
  19997. %@AB@%_nheapmin%@AE@%                                                                   
  19998.  
  19999. %@NL@%
  20000. %@3@%%@CR:C6A-B0017   @%%@AB@%B.2.5  Making Static Data Available to the Heap%@AE@%%@EH@%%@NL@%
  20001. %@NL@%
  20002. The %@AB@%_heapadd%@AE@% function is new. It allows the user to make unused static data
  20003. available to the heap.  %@NL@%
  20004. %@NL@%
  20005. %@NL@%
  20006. %@3@%%@CR:C6A-B0018   @%%@AB@%B.2.6  Long Doubles%@AE@%%@EH@%%@NL@%
  20007. %@NL@%
  20008. Microsoft C version 5.1 treated %@AB@%double%@AE@% and %@AB@%long double%@AE@% as syntactically
  20009. different types that were semantically equal. Both types were stored in
  20010. memory as 64-bit quantities. For purposes of type-checking, %@AB@%long double%@AE@% and
  20011. %@AB@%double%@AE@% have always been different types.  %@NL@%
  20012. %@NL@%
  20013. Because the 80%@AI@%x%@AE@%87 family of math coprocessors supports an 80-bit
  20014. floating-point type, Microsoft C version 6.0 stores %@AB@%long double%@AE@% variables in
  20015. the 80%@AI@%x%@AE@%87 10-byte (80-bit) form.  %@NL@%
  20016. %@NL@%
  20017. Certain functions have been modified to handle the %@AB@%long double%@AE@% type. The
  20018. %@AB@%printf%@AE@% and %@AB@%scanf%@AE@% family of functions supports %@AB@%long double%@AE@% values with the
  20019. trailing %@AB@%l%@AE@%. The library contains new versions of the transcendental
  20020. functions as well as intrinsic forms that accept %@AB@%long double%@AE@% arguments.  %@NL@%
  20021. %@NL@%
  20022. %@NL@%
  20023. %@3@%%@CR:C6A-B0019   @%%@AB@%B.2.7  Long Double Functions%@AE@%%@EH@%%@NL@%
  20024. %@NL@%
  20025. All the functions below are defined in the standard include file MATH.H.
  20026. They return %@AB@%long double%@AE@% values and results and error codes analogous to the
  20027. double versions.  %@NL@%
  20028. %@NL@%
  20029. %@TH:  10   630 01 08 08 60 @%
  20030. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20031. %@AB@%acosl%@AE@%   %@AB@%expl%@AE@%    %@AB@%_matherrl%@AE@%
  20032. %@AB@%asinl%@AE@%   %@AB@%fabsl%@AE@%   %@AB@%modfl%@AE@%
  20033. %@AB@%atanl%@AE@%   %@AB@%floorl%@AE@%  %@AB@%powl%@AE@%
  20034. %@AB@%atan2l%@AE@%  %@AB@%fmodl%@AE@%   %@AB@%sinl%@AE@%
  20035. %@AB@%_atold%@AE@%  %@AB@%frexpl%@AE@%  %@AB@%sinhl%@AE@%
  20036. %@AB@%cabsl%@AE@%   %@AB@%hypotl%@AE@%  %@AB@%sqrtl%@AE@%
  20037. %@AB@%ceill%@AE@%   %@AB@%ldexpl%@AE@%  %@AB@%tanl%@AE@%
  20038. %@AB@%cosl%@AE@%    %@AB@%logl%@AE@%    %@AB@%tanhl%@AE@%
  20039. %@AB@%coshl%@AE@%   %@AB@%log10l%@AE@%
  20040. %@TE:  10   630 01 08 08 60 @%
  20041.  
  20042. %@NL@%
  20043. %@3@%%@CR:C6A-B0020   @%%@AB@%B.2.8  Model-Independent String and Memory Functions%@AE@%%@EH@%%@NL@%
  20044. %@NL@%
  20045. The following functions make it easier to write mixed-model programs by
  20046. providing model-independent (large model) forms for most of the standard
  20047. string and memory functions. These functions can be called from any point in
  20048. any program, no matter which memory model has been selected. These functions
  20049. take only far pointers as arguments. Thus, any data item, near or far, in
  20050. any combination, can be handled.  %@NL@%
  20051. %@NL@%
  20052. The names of these functions are the same as the model-dependent forms,
  20053. except they include an %@AB@%_f %@AE@%prefix. For example, %@AB@%_fstrlen %@AE@%is the
  20054. model-independent version of the %@AB@%strlen %@AE@%function.  %@NL@%
  20055. %@NL@%
  20056. The functions listed below are defined in the standard include file
  20057. STRING.H.  %@NL@%
  20058. %@NL@%
  20059. %@NL@%
  20060. %@4@%%@AB@%Memory Functions%@AE@%%@EH@%%@NL@%
  20061. %@NL@%
  20062. %@TH:   5   340 01 29 47 @%
  20063. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20064. %@AB@%_fmemccpy %@AE@%                   %@AB@%_fmemcpy%@AE@%
  20065. %@AB@%_fmemchr%@AE@%                     %@AB@%_fmemmove%@AE@%
  20066. %@AB@%_fmemcmp%@AE@%                     _fmemset
  20067. %@AB@%_fmemicmp%@AE@%                    
  20068. %@TE:   5   340 01 29 47 @%
  20069.  
  20070. %@NL@%
  20071. %@4@%%@AB@%String Functions%@AE@%%@EH@%%@NL@%
  20072. %@NL@%
  20073. %@TH:   8   520 01 11 12 53 @%
  20074. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20075. %@AB@%_fstrcat%@AE@%   _fstrlwr    %@AB@%_fstrrchr%@AE@%
  20076. %@AB@%_fstrchr%@AE@%   %@AB@%_fstrncat%@AE@%   _fstrrev
  20077. %@AB@%_fstrcmp%@AE@%   _fstrncmp   %@AB@%_fstrset%@AE@%
  20078. %@AB@%_fstricmp%@AE@%  _fstrnicmp  %@AB@%_fstrspn%@AE@%
  20079. %@AB@%_fstrcpy%@AE@%   _fstrncpy   %@AB@%_fstrstr%@AE@%
  20080. %@AB@%_fstrcspn%@AE@%  %@AB@%_fstrnset%@AE@%   _fstrtok
  20081. %@AB@%_fstrlen%@AE@%   _fstrpbrk   %@AB@%_fstrupr %@AE@%
  20082. %@TE:   8   520 01 11 12 53 @%
  20083.  
  20084. %@NL@%
  20085. %@4@%%@AB@%String Duplication Functions%@AE@%%@EH@%%@NL@%
  20086. %@NL@%
  20087. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20088. %@AB@%_fstrdup%@AE@%                                                                    
  20089. %@AB@%_nstrdup%@AE@%                                                                    
  20090.  
  20091. %@NL@%
  20092. %@3@%%@CR:C6A-B0021   @%%@AB@%B.2.9  Mixed-Model Memory Allocation Support%@AE@%%@EH@%%@NL@%
  20093. %@NL@%
  20094. The following functions are based on %@AB@%realloc%@AE@%, %@AB@%calloc%@AE@%, and %@AB@%expand%@AE@%, but they
  20095. affect only near memory or far memory. MALLOC.H contains the function
  20096. prototypes.  %@NL@%
  20097. %@NL@%
  20098. %@TH:   4   271 01 28 48 @%
  20099. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20100. %@AB@%_fcalloc%@AE@%                    _ncalloc
  20101. %@AB@%_fexpand%@AE@%                    _nexpand
  20102. %@AB@%_frealloc%@AE@%                   _nrealloc
  20103. %@TE:   4   271 01 28 48 @%
  20104.  
  20105. %@NL@%
  20106. %@3@%%@CR:C6A-B0022   @%%@AB@%B.2.10  The _fastcall Attribute (/Gr Option)%@AE@%%@EH@%%@NL@%
  20107. %@NL@%
  20108. Individual function prototypes can be declared with the new attribute
  20109. %@AB@%_fastcall%@AE@%.  %@NL@%
  20110. %@NL@%
  20111. The /Gr option enables the fastcall function-calling convention for all
  20112. functions that are not explicitly prototyped with the %@AB@%_cdecl%@AE@%, %@AB@%_pascal%@AE@%, or
  20113. %@AB@%_fortran %@AE@%attributes. Using /Gr on the command line causes each function in
  20114. the module to compile as %@AB@%_fastcall%@AE@% unless the function is declared with a
  20115. conflicting attribute, or the name of the function is %@AB@%main%@AE@%.  %@NL@%
  20116. %@NL@%
  20117. When you use the /Gr option, all functions are assumed to use the %@AB@%_fastcall
  20118. %@AB@%%@AE@%convention. As a result, to use any run-time library functions, you must
  20119. either include the standard include files or explicitly prototype the
  20120. function you want to call.  %@NL@%
  20121. %@NL@%
  20122. A fastcall function receives up to three 16-bit arguments, passed in
  20123. registers rather than on the stack. Arguments are passed in the AX, BX, and
  20124. DX registers. This may change in future versions of the compiler.  %@NL@%
  20125. %@NL@%
  20126. The argument types and their potential register assignments are  %@NL@%
  20127. %@NL@%
  20128. %@AB@%Argument%@AE@%                          %@AB@%Registers%@AE@%
  20129. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20130. character (3)                     AL, DL, BL
  20131.  
  20132. short integer (3)                 AX, DX, BX
  20133.  
  20134. near pointer (3)                  BX, AX, DX
  20135.  
  20136. long integer (1)                  DX:AX
  20137.  
  20138. far pointer (1)                   ES:BX
  20139.  
  20140. If the registers for a particular class have already been used, or if an
  20141. argument is not one of the five types listed above, it is pushed on the
  20142. stack as usual. An argument list of types %@AB@%long%@AE@%, %@AB@%float%@AE@%, %@AB@%short %@AE@%would pass the
  20143. %@AB@%long %@AE@%in DX:AX, push the %@AB@%float%@AE@%, and pass the %@AB@%short %@AE@%in BX.  %@NL@%
  20144. %@NL@%
  20145. The treatment of character arguments depends further on prototypes. If there
  20146. is no prototype, the argument is promoted to %@AB@%short %@AE@%and the rules for short
  20147. integers apply. Only if the argument is prototyped as a %@AB@%char %@AE@%do the
  20148. character rules apply.  %@NL@%
  20149. %@NL@%
  20150. The %@AB@%_fastcall %@AE@%convention is not compatible with any of the following
  20151. attributes: %@AB@%_interrupt%@AE@%, %@AB@%_saveregs%@AE@%, %@AB@%_export%@AE@%, %@AB@%_cdecl%@AE@%, %@AB@%_fortran%@AE@%, or %@AB@%_pascal%@AE@%.  %@NL@%
  20152. %@NL@%
  20153. See Chapter 1, "Optimizing C Programs."  %@NL@%
  20154. %@NL@%
  20155. %@NL@%
  20156. %@3@%%@CR:C6A-B0023   @%%@AB@%B.2.11  Drive and Directory Functions%@AE@%%@EH@%%@NL@%
  20157. %@NL@%
  20158. Several new functions make it easier to get and set the current drive and
  20159. the current directory. The prototypes for the following routines are in
  20160. DIRECT.H:%@CR:C6A-B0024   @%  %@NL@%
  20161. %@NL@%
  20162. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20163. %@AB@%_chdrive%@AE@%                                                                    
  20164. %@AB@%_fullpath%@AE@%                                                                   
  20165. %@AB@%_getdrive%@AE@%                                                                   
  20166. %@AB@%_getdcwd%@AE@%                                                                    
  20167.  
  20168. %@NL@%
  20169. %@3@%%@CR:C6A-B0025   @%%@AB@%B.2.12  Text Output Functions for OS/2%@AE@%%@EH@%%@NL@%
  20170. %@NL@%
  20171. Several text-mode screen functions have been added to Microsoft C 6.0 for
  20172. OS/2. With the exception of the new %@AB@%_scrolltextwindow %@AE@%function, they are
  20173. identical to what is defined in real mode, except for any references to
  20174. behavior in graphics modes. The following routines are located in
  20175. GRTEXT.LIB, and the prototypes are in GRAPH.H:  %@NL@%
  20176. %@NL@%
  20177. %@TH:   7   561 01 18 18 40 @%
  20178. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20179. %@AB@%_clearscreen%@AE@%      _getvideoconfig   %@AB@%_settextrows%@AE@%
  20180. %@AB@%_displaycursor%@AE@%    _outtext          %@AB@%_settextwindow%@AE@%
  20181. %@AB@%_getbkcolor%@AE@%       _setbkcolor       %@AB@%_setvideomode%@AE@%
  20182. %@AB@%_gettextcolor%@AE@%     _settextcolor     %@AB@%_setvideomoderows%@AE@%
  20183. %@AB@%_gettextcursor%@AE@%    _settextcursor    _scrolltextwindow
  20184. %@AB@%_gettextposition%@AE@%  _settextposition  %@AB@%_wrapon %@AE@%
  20185. %@TE:   7   561 01 18 18 40 @%
  20186.  
  20187. See Part 4 of this manual, "OS/2 Support."  %@NL@%
  20188. %@NL@%
  20189. %@NL@%
  20190. %@2@%%@CR:C6A-B0026   @%%@AB@%B.3  New Features%@AE@%%@EH@%%@NL@%
  20191. %@NL@%
  20192. The features described in Sections B.3.1-B.3.10 are new to version 6.0.  %@NL@%
  20193. %@NL@%
  20194. %@NL@%
  20195. %@3@%%@CR:C6A-B0027   @%%@AB@%B.3.1  Strings and Macros%@AE@%%@EH@%%@NL@%
  20196. %@NL@%
  20197. The compiler now allows longer string literals (up to 4K) and longer macro
  20198. expansions (up to 6K).  %@NL@%
  20199. %@NL@%
  20200. %@NL@%
  20201. %@3@%%@CR:C6A-B0028   @%%@AB@%B.3.2  CL Options%@AE@%%@EH@%%@NL@%
  20202. %@NL@%
  20203. The following options are new to Microsoft C 6.0:%@CR:C6A-B0029   @%  %@NL@%
  20204. %@NL@%
  20205. %@AB@%Option%@AE@%                            %@AB@%Action%@AE@%
  20206. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20207. /AT                               Compiles in tiny model (.COM files).
  20208.  
  20209. /Fr« %@AI@%filename%@AE@%»                    Outputs source browser information file.
  20210.  
  20211. /FR«%@AI@% filename%@AE@%»                    Outputs extended source browser 
  20212.                                   information file.
  20213.  
  20214. /Gd                               Forces %@AB@%_cdecl %@AE@%calling conventions.
  20215.  
  20216. /Gr                               Enables register (%@AB@%_fastcall%@AE@%) 
  20217.                                   function-calling
  20218.                                   conventions.
  20219.  
  20220. /MA%@AI@%masmoption%@AE@%                     Supports invocation of the assembler 
  20221.                                   using the CL driver. All MASM-supported 
  20222.                                   options are accepted. In addition, the 
  20223.                                   compiler recognizes file names with .ASM
  20224.                                   suffixes and passes them directly to 
  20225.                                   MASM.
  20226.  
  20227. /MD-                              Uses C run-time as DLL option. Defaults 
  20228.                                   to
  20229.                                   /ALw /FPi /G2 /DDLL /DMT and inhibits 
  20230.                                   library search records.
  20231.  
  20232. /ML                               Links C run-time as part of a 
  20233.                                   dynamic-link library (DLL). Defaults to 
  20234.                                   /ALw /FPa /G2 /DMT and changes library 
  20235.                                   search record to LLIBCDLL.LIB.
  20236.  
  20237. /MT                               Enables multithread option. Defaults to
  20238.                                   /ALw /FPi /G2 /DMT and changes library
  20239.                                   search record to LLIBCMT.LIB.
  20240.  
  20241. /Oe                               Enables global register allocation.
  20242.  
  20243. /Og                               Enables global optimizations and global 
  20244.                                   common subexpressions (CSEs).
  20245.  
  20246. /Ox                               Is now equivalent to /Ocegilt /Gs. Note 
  20247.                                   that this implies that maximum 
  20248.                                   optimization includes the %@AB@%_fastcall%@AE@% 
  20249.                                   function-calling convention.
  20250.  
  20251. /Oz                               Enables aggressive optimizations.
  20252.  
  20253. /Ta %@AI@%name%@AE@%                          Specifies that%@AI@% name %@AE@%is to be treated as 
  20254.                                   an assembler input file.
  20255.  
  20256. /W4                               Turns on extra warning level which 
  20257.                                   supports more detailed (LINT-like) 
  20258.                                   warnings and recognition of ANSI 
  20259.                                   violations.
  20260.  
  20261. /WX                               Causes warnings to be treated as errors.
  20262.                                   If a warning occurs, the .OBJ file is 
  20263.                                   not created.
  20264.  
  20265. %@NL@%
  20266. %@3@%%@CR:C6A-B0030   @%%@AB@%B.3.3  Tiny Memory Model (.COM Files)%@AE@%%@EH@%%@NL@%
  20267. %@NL@%
  20268. Microsoft C 6.0 now supports the tiny memory model, which produces .COM
  20269. rather than .EXE files (for DOS only).  %@NL@%
  20270. %@NL@%
  20271. The /AT option selects the tiny model. This forces the linker to use options
  20272. /NOE and /TINY. Within the linker, /TINY turns on /FARCALLTRANSLATION to
  20273. help eliminate far segment relocations. If you link your own .OBJ files,
  20274. link with CRTCOM.OBJ.  %@NL@%
  20275. %@NL@%
  20276. %@NL@%
  20277. %@3@%%@CR:C6A-B0031   @%%@AB@%B.3.4  The Optimize Pragma%@AE@%%@EH@%%@NL@%
  20278. %@NL@%
  20279. The %@AB@%optimize %@AE@%pragma turns optimizing options on or off:  %@NL@%
  20280. %@NL@%
  20281. %@AS@%  #pragma optimize("<optimization switch list>",{off|on})%@AE@%%@NL@%
  20282. %@NL@%
  20283. where %@AI@%<optimization switch list>%@AE@% can be an empty list or one or more of the
  20284. following: a, c, e, g, l, w, n, p, t, and z. For example,  %@NL@%
  20285. %@NL@%
  20286. %@AS@%  #pragma optimize("lp",on) /* equivalent to /Olp */
  20287. %@AS@%  #pragma optimize("",off)  /* turns off all optimization */
  20288. %@AS@%  #pragma optimize("",on)  /* restores default settings */%@AE@%%@NL@%
  20289. %@NL@%
  20290. See Chapter 1, "Optimizing C Programs."  %@NL@%
  20291. %@NL@%
  20292. %@NL@%
  20293. %@3@%%@CR:C6A-B0032   @%%@AB@%B.3.5  Nameless Structures and Unions%@AE@%%@EH@%%@NL@%
  20294. %@NL@%
  20295. Both %@AB@%struct %@AE@%and %@AB@%union %@AE@%declarations can now be specified without a declarator
  20296. when they are members of another structure or union.  %@NL@%
  20297. %@NL@%
  20298. A nameless union would look like this:  %@NL@%
  20299. %@NL@%
  20300. %@AS@%  struct str
  20301. %@AS@%  {
  20302. %@AS@%     int a,b;
  20303. %@AS@%     union           /* unnamed union */
  20304. %@AS@%     {
  20305. %@AS@%        char c[4];
  20306. %@AS@%        long l;
  20307. %@AS@%        float f;
  20308. %@AS@%     };
  20309. %@AS@%     char c_array[10];
  20310. %@AS@%  } my_str;
  20311. %@AS@%  .
  20312. %@AS@%  .
  20313. %@AS@%  .
  20314. %@AS@%  my_str.l == 0L;%@AE@%%@NL@%
  20315. %@NL@%
  20316. A nameless structure would look like this:  %@NL@%
  20317. %@NL@%
  20318. %@AS@%  struct s1
  20319. %@AS@%  {
  20320. %@AS@%     int a,b,c;
  20321. %@AS@%  };
  20322. %@AS@%  
  20323. %@AS@%  struct s2
  20324. %@AS@%  {
  20325. %@AS@%     float y;
  20326. %@AS@%     struct s1;
  20327. %@AS@%     char str[10];
  20328. %@AS@%  } *p_s2;
  20329. %@AS@%  .
  20330. %@AS@%  .
  20331. %@AS@%  .
  20332. %@AS@%  
  20333. %@AS@%  p_s2->b = 100;%@AE@%%@NL@%
  20334. %@NL@%
  20335. %@NL@%
  20336. %@3@%%@CR:C6A-B0033   @%%@AB@%B.3.6  Unsized Arrays as the Last Member of a Structure%@AE@%%@EH@%%@NL@%
  20337. %@NL@%
  20338. The compiler now allows an unsized or zero-sized array as the last member of
  20339. a structure. The declaration of such a structure would look like this:  %@NL@%
  20340. %@NL@%
  20341. %@AS@%  struct var_length
  20342. %@AS@%  {
  20343. %@AS@%     <set of declarations>;
  20344. %@AS@%     <type> array[];
  20345. %@AS@%  };%@AE@%%@NL@%
  20346. %@NL@%
  20347. Unsized arrays can appear only as the last member of a structure. Structures
  20348. containing unsized array declarations can be nested within other structures
  20349. as long as no further members are declared in any enclosing structures.
  20350. Arrays of such structures are not allowed.  %@NL@%
  20351. %@NL@%
  20352. The %@AB@%sizeof %@AE@%operator, when applied to a variable of this type or to the type
  20353. itself, assumes 0 for the size of the array.  %@NL@%
  20354. %@NL@%
  20355. %@NL@%
  20356. %@3@%%@CR:C6A-B0034   @%%@AB@%B.3.7  Improved Warnings%@AE@%%@EH@%%@NL@%
  20357. %@NL@%
  20358. A new warning level four (CL option /W4) has been added for the following
  20359. warnings:  %@NL@%
  20360. %@NL@%
  20361. %@NL@%
  20362.   ■   Detection of unused global variables%@NL@%
  20363. %@NL@%
  20364.   ■   Expressions without side effects%@NL@%
  20365. %@NL@%
  20366.   ■   Nonportable (non-ANSI) constructs%@NL@%
  20367. %@NL@%
  20368.   ■   Local variable referenced before being initialized%@NL@%
  20369. %@NL@%
  20370.   ■   Undefined or implementation-defined constructs%@NL@%
  20371. %@NL@%
  20372. %@NL@%
  20373. %@NL@%
  20374. %@3@%%@CR:C6A-B0035   @%%@AB@%B.3.8  Macros%@AE@%%@EH@%%@NL@%
  20375. %@NL@%
  20376. The number of macros definable with /D options has increased from 20 to 30.
  20377. %@NL@%
  20378. %@NL@%
  20379. %@NL@%
  20380. %@3@%%@CR:C6A-B0036   @%%@AB@%B.3.9  Improved Multithread Support in OS/2%@AE@%%@EH@%%@NL@%
  20381. %@NL@%
  20382. The number of OS/2 threads supported at run time has increased from 32 to
  20383. the operating system limit. Three new options aid development of multithread
  20384. applications and dynamic-link libraries:  %@NL@%
  20385. %@NL@%
  20386. %@NL@%
  20387.   1.  /MT for building multithread programs. It implies /ALw /FPi /G2 /D MT,
  20388.       and changes the library search record emitted in the object file to
  20389.       reference LLIBCMT.%@NL@%
  20390. %@NL@%
  20391.   2.  /ML for building a DLL that uses the C run-time library. It implies
  20392.       /ALw /FPa /G2 /D MT, and changes the library search record emitted  in
  20393.       the object file to reference LLIBCDLL.%@NL@%
  20394. %@NL@%
  20395.   3.  /MD for building .EXE files and DLLs that share a C run-time DLL. It
  20396.       implies /ALw /FPi /G2 /DDLL /D MT, and no library search records are
  20397.       emitted in the object file.%@NL@%
  20398. %@NL@%
  20399. %@NL@%
  20400. %@NL@%
  20401. %@3@%%@CR:C6A-B0037   @%%@AB@%B.3.10  Pipe Support in OS/2%@AE@%%@EH@%%@NL@%
  20402. %@NL@%
  20403. Microsoft C 6.0 supports pipes as part of the file I/O system. The functions
  20404. listed below are defined in the standard include file IO.H:  %@NL@%
  20405. %@NL@%
  20406. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20407. %@AB@%_pipe%@AE@%                                                                       
  20408. %@AB@%_popen%@AE@%                                                                      
  20409. %@AB@%_pclose%@AE@%                                                                     
  20410.  
  20411. %@NL@%
  20412. %@2@%%@CR:C6A-B0038   @%%@AB@%B.4  Differences in Code Generation%@AE@%%@EH@%%@NL@%
  20413. %@NL@%
  20414. This section lists ways in which the executable files produced by Microsoft
  20415. C 6.0 may differ from the files produced by previous versions of the
  20416. compiler.  %@NL@%
  20417. %@NL@%
  20418. %@NL@%
  20419. %@3@%%@CR:C6A-B0039   @%%@AB@%B.4.1  Speed and Space Improvements%@AE@%%@EH@%%@NL@%
  20420. %@NL@%
  20421. Executable files are smaller and faster.  %@NL@%
  20422. %@NL@%
  20423. %@NL@%
  20424. %@3@%%@CR:C6A-B0040   @%%@AB@%B.4.2  Code Quality%@AE@%%@EH@%%@NL@%
  20425. %@NL@%
  20426. Microsoft C 6.0 generates improved local code in default optimization cases
  20427. and, under full optimization, supports global (function level) register
  20428. allocation and common subexpressions (CSEs), loop optimizations, parameter
  20429. passing through registers, and generation of in-line code for certain
  20430. intrinsic functions.  %@NL@%
  20431. %@NL@%
  20432. %@NL@%
  20433. %@3@%%@CR:C6A-B0041   @%%@AB@%B.4.3  Floating-Point Code Generation%@AE@%%@EH@%%@NL@%
  20434. %@NL@%
  20435. In Microsoft C 6.0, the /FPi87 option suppresses the fixups previously used
  20436. for emulation. Pure coprocessor instructions are now emitted. This makes
  20437. object files smaller and speeds up linking, in addition to making in-line
  20438. assembly easier to use.  %@NL@%
  20439. %@NL@%
  20440. In version 5.1, /FPi and /FPi87 generated the same code; the only difference
  20441. was the library. In C 6.0, the two options generate different code. It is no
  20442. longer possible to force /FPi87 to act like /FPi. If you use /FPi87, the
  20443. math coprocessor must be in the computer on which the program is running.  %@NL@%
  20444. %@NL@%
  20445. Note that if you use /FPi87 you must link with mLIB7, not mLIBCE.  %@NL@%
  20446. %@NL@%
  20447. %@NL@%
  20448. %@3@%%@CR:C6A-B0042   @%%@AB@%B.4.4  Intrinsic Functions%@AE@%%@EH@%%@NL@%
  20449. %@NL@%
  20450. The intrinsic function optimization option (/Oi) causes the compiler to
  20451. generate in-line code for the following functions:  %@NL@%
  20452. %@NL@%
  20453. %@TH:   8   467 01 10 08 58 @%
  20454. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20455. %@AB@%abs%@AE@%       _lrotl  %@AB@%_rotl%@AE@%
  20456. %@AB@%_disable%@AE@%  _lrotr  %@AB@%_rotr%@AE@%
  20457. %@AB@%_enable%@AE@%   memcmp  %@AB@%strcat%@AE@%
  20458. %@AB@%ffabs%@AE@%     memcpy  %@AB@%strcmp%@AE@%
  20459. %@AB@%inp%@AE@%       memset  %@AB@%strcpy%@AE@%
  20460. %@AB@%inpw%@AE@%      outp    %@AB@%strlen%@AE@%
  20461. %@AB@%labs%@AE@%      outpw   %@AB@%strset%@AE@%
  20462. %@TE:   8   467 01 10 08 58 @%
  20463.  
  20464. The compiler does not generate in-line code for the following functions,
  20465. although it will modify the calling convention to pass the arguments on the
  20466. floating-point chip:  %@NL@%
  20467. %@NL@%
  20468. %@TH:  13   759 01 07 08 61 @%
  20469. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20470. %@AB@%acos%@AE@%   %@AB@%pow%@AE@%     %@AB@%coshl%@AE@%
  20471. %@AB@%asin%@AE@%   %@AB@%sin%@AE@%     %@AB@%expl%@AE@%
  20472. %@AB@%atan%@AE@%   %@AB@%sinh%@AE@%    %@AB@%floorl%@AE@%
  20473. %@AB@%atan2%@AE@%  %@AB@%sqrt%@AE@%    %@AB@%fmodl%@AE@%
  20474. %@AB@%ceil%@AE@%   %@AB@%tan%@AE@%     logl
  20475. %@AB@%cos%@AE@%    %@AB@%tanh%@AE@%    %@AB@%log10l%@AE@%
  20476. %@AB@%cosh%@AE@%   %@AB@%acosl%@AE@%   %@AB@%powl%@AE@%
  20477. %@AB@%exp%@AE@%    %@AB@%asinl%@AE@%   sinl
  20478. %@AB@%floor%@AE@%  %@AB@%atanl%@AE@%   %@AB@%sinhl%@AE@%
  20479. %@AB@%fmod%@AE@%   atan2l  %@AB@%sqrtl%@AE@%
  20480. %@AB@%log%@AE@%    %@AB@%ceill%@AE@%   %@AB@%tanl%@AE@%
  20481. %@AB@%log10%@AE@%  cosl    %@AB@%tanhl%@AE@%
  20482. %@TE:  13   759 01 07 08 61 @%
  20483.  
  20484. %@NL@%
  20485. %@2@%%@CR:C6A-B0043   @%%@AB@%B.5  Changes and Deletions%@AE@%%@EH@%%@NL@%
  20486. %@NL@%
  20487. The changes and deletions listed in this section have a high probability of
  20488. affecting existing programs.  %@NL@%
  20489. %@NL@%
  20490. %@NL@%
  20491. %@3@%%@CR:C6A-B0044   @%%@AB@%B.5.1  Deleted Features%@AE@%%@EH@%%@NL@%
  20492. %@NL@%
  20493. The %@AB@%data_seg%@AE@% pragma has been deleted.  %@NL@%
  20494. %@NL@%
  20495. The memory management routine %@AB@%sbrk%@AE@% has been deleted.  %@NL@%
  20496. %@NL@%
  20497. The compiler and tools do not run under DOS 2.1. The run-time files produced
  20498. by the compiler and linker will continue to run under DOS 2.1.  %@NL@%
  20499. %@NL@%
  20500. %@NL@%
  20501. %@3@%%@CR:C6A-B0045   @%%@AB@%B.5.2  Evaluation of Real Expressions%@AE@%%@EH@%%@NL@%
  20502. %@NL@%
  20503. Real expressions inside parentheses are now evaluated according to the
  20504. semantics of the parentheses. For example, in the expression  %@NL@%
  20505. %@NL@%
  20506. %@AS@%  ((r1 / r2) * r3)%@AE@%%@NL@%
  20507. %@NL@%
  20508. the division is performed before the multiplication. Previous versions of
  20509. the compiler might have reordered the operations.  %@NL@%
  20510. %@NL@%
  20511. %@NL@%
  20512. %@3@%%@CR:C6A-B0046   @%%@AB@%B.5.3  Default Optimizations%@AE@%%@EH@%%@NL@%
  20513. %@NL@%
  20514. Version 6.0 performs more extensive optimizations than version 5.1. This
  20515. implies that code that had aliasing but worked with the /Oa option in 5.1
  20516. might not work with version 6.0 and /Oa. Also, because of the improved
  20517. optimizations, the /Od option should be used to turn off all optimizing
  20518. before you begin debugging with CodeView.  %@NL@%
  20519. %@NL@%
  20520. %@NL@%
  20521. %@3@%%@CR:C6A-B0047   @%%@AB@%B.5.4  Sign Extension of char Arguments%@AE@%%@EH@%%@NL@%
  20522. %@NL@%
  20523. Previous versions of Microsoft C would sign-extend %@AB@%char %@AE@%arguments to %@AB@%int
  20524. %@AB@%%@AE@%size before passing them to a second function. Version 6.0 does not extend
  20525. the sign if the function is prototyped and the prototype includes a %@AB@%char%@AE@%
  20526. argument. The most-significant byte is considered undefined.  %@NL@%
  20527. %@NL@%
  20528. %@NL@%
  20529. %@3@%%@CR:C6A-B0048   @%%@AB@%B.5.5  Conditional Compilation and Signed Values%@AE@%%@EH@%%@NL@%
  20530. %@NL@%
  20531. Version 5.1 of Microsoft C treated conditional compilation expressions as
  20532. %@AB@%signed long%@AE@% values. Version 6.0 evaluates these expressions using the same
  20533. rules as expressions in C. For example,  %@NL@%
  20534. %@NL@%
  20535. %@AS@%  #if 0xFFFFFFFFL > 1UL
  20536. %@AS@%  .
  20537. %@AS@%  .
  20538. %@AS@%  .
  20539. %@AS@%  #endif%@AE@%%@NL@%
  20540. %@NL@%
  20541. The expression evaluates to be true. It was evaluated as false in version
  20542. 5.1.  %@NL@%
  20543. %@NL@%
  20544. %@NL@%
  20545. %@3@%%@CR:C6A-B0049   @%%@AB@%B.5.6  The const and volatile Qualifiers%@AE@%%@EH@%%@NL@%
  20546. %@NL@%
  20547. The %@AB@%const %@AE@% and %@AB@%volatile %@AE@%qualifiers must be placed after the type they
  20548. qualify. The declaration  %@NL@%
  20549. %@NL@%
  20550. %@AS@%  int (const *p);%@AE@%%@NL@%
  20551. %@NL@%
  20552. is now treated as a syntax error. Previous versions of the compiler would
  20553. accept such a construction.  %@NL@%
  20554. %@NL@%
  20555. The following declarations are legal:  %@NL@%
  20556. %@NL@%
  20557. %@AS@%  int const *p_ci;  /* pointer to constant int */
  20558. %@AS@%  int const (*p_ci); /* pointer to constant int */
  20559. %@AS@%  int *const cp_i;  /* constant pointer to int */
  20560. %@AS@%  int (*const cp_i); /* constant pointer to int */%@AE@%%@NL@%
  20561. %@NL@%
  20562. %@NL@%
  20563. %@3@%%@CR:C6A-B0050   @%%@AB@%B.5.7  Memory Allocation%@AE@%%@EH@%%@NL@%
  20564. %@NL@%
  20565. The %@AB@%_fmalloc %@AE@%function attempts to allocate far memory. It previously called
  20566. %@AB@%_nmalloc %@AE@%if far memory was not available. Now it returns a null pointer if
  20567. far memory isn't available, even if near memory is available.  %@NL@%
  20568. %@NL@%
  20569. %@NL@%
  20570. %@3@%%@CR:C6A-B0051   @%%@AB@%B.5.8  Memory Used by Command-Line Arguments%@AE@%%@EH@%%@NL@%
  20571. %@NL@%
  20572. Previous versions of the compiler placed the command-line argument strings
  20573. and environment strings in the near heap. Now they are allocated though
  20574. %@AB@%malloc%@AE@%, which means that they will be in far memory in compact and large
  20575. models.  %@NL@%
  20576. %@NL@%
  20577. %@NL@%
  20578. %@3@%%@CR:C6A-B0052   @%%@AB@%B.5.9  Format Specifiers in printf%@AE@%%@EH@%%@NL@%
  20579. %@NL@%
  20580. The %@AB@%printf%@AE@% format specifier modifiers %@AB@%N%@AE@%, %@AB@%F%@AE@%, %@AB@%h%@AE@%, and%@AB@% l%@AE@% have changed.  %@NL@%
  20581. %@NL@%
  20582. The specifier %@AB@%%Np%@AE@% is a synonym for %@AB@%%hp%@AE@%, but the latter is preferred.
  20583. Likewise, %@AB@%%Fp%@AE@% is a synonym for %@AB@%%lp%@AE@%.  %@NL@%
  20584. %@NL@%
  20585. For %@AB@%scanf%@AE@%, %@AB@%N%@AE@% and %@AB@%F%@AE@% refer to the distance to the object being read in; that
  20586. is, whether the pointer itself is allocated near or far. The modifiers %@AB@%h%@AE@% and%@AB@%
  20587. %@AB@%l%@AE@% refer to the size of the object (16-bit near pointer or 32-bit far
  20588. pointer). In these examples,  %@NL@%
  20589. %@NL@%
  20590. %@AS@%  scanf("%Nlp", n_fp);
  20591. %@AS@%  scanf("%Fhp", f_np);%@AE@%%@NL@%
  20592. %@NL@%
  20593. the first line reads in an address that resides in near memory (%@AS@%N%@AE@%) but holds
  20594. a 32-bit far pointer variable (%@AS@%lp%@AE@%). The second line reads in a near pointer
  20595. value (%@AS@%hp%@AE@%) into a pointer variable that resides in far memory (%@AS@%F%@AE@%).  %@NL@%
  20596. %@NL@%
  20597. %@NL@%
  20598. %@3@%%@CR:C6A-B0053   @%%@AB@%B.5.10  Functions that Return Float Values%@AE@%%@EH@%%@NL@%
  20599. %@NL@%
  20600. In Microsoft C 5.1, a prototype or definition such as  %@NL@%
  20601. %@NL@%
  20602. %@AS@%  float funcname();%@AE@%%@NL@%
  20603. %@NL@%
  20604. was interpreted as %@AS@%  %@AE@%%@NL@%
  20605. %@NL@%
  20606. %@AS@%  double funcname()%@AE@%%@NL@%
  20607. %@NL@%
  20608. Version 6.0 interprets it as %@AS@%  %@AE@%%@NL@%
  20609. %@NL@%
  20610. %@AS@%  float %@AE@%%@NL@%
  20611. %@NL@%
  20612. %@NL@%
  20613. %@NL@%
  20614. %@NL@%
  20615. %@NL@%
  20616. %@NL@%
  20617. %@CR:C6A-C0001   @%%@1@%%@AB@%Appendix C  Implementation-Defined Behavior%@AE@%%@EH@%%@NL@%
  20618. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20619. %@NL@%
  20620. The American National Standards Institute (ANSI) Standard for the C
  20621. programming language contains an appendix called "Portability Issues." The
  20622. ANSI appendix lists areas of the C language that ANSI leaves open to each
  20623. particular implementation. This appendix describes how Microsoft C handles
  20624. these implementation-defined areas of the C language.  %@NL@%
  20625. %@NL@%
  20626. This appendix follows the same order as the ANSI Standard appendix. Each
  20627. item covered includes references to the ANSI chapter and section that
  20628. explains the implementation-defined behavior.  %@NL@%
  20629. %@NL@%
  20630. ────────────────────────────────────────────────────────────────────────────%@NL@%
  20631. NOTE
  20632.  
  20633. %@AI@%This appendix describes the U.S. English-language version of the C compiler
  20634. %@AI@%only. Foreign-language implementations of Microsoft C may differ slightly.%@AE@%%@NL@%
  20635. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  20636. %@NL@%
  20637. %@NL@%
  20638. %@2@%%@CR:C6A-C0002   @%%@AB@%C.1  Translation%@AE@%%@EH@%%@NL@%
  20639. %@NL@%
  20640. %@NL@%
  20641. %@3@%%@CR:C6A-C0003   @%%@AB@%C.1.1  Diagnostics%@AE@%%@EH@%%@NL@%
  20642. %@NL@%
  20643. %@AB@%How a diagnostic is identified (2.1.1.3)%@AE@%  %@NL@%
  20644. %@NL@%
  20645. Microsoft C produces error messages in the form:  %@NL@%
  20646. %@NL@%
  20647. %@AS@%  filename(line-number) : diagnostic Cnumber message%@AE@%%@NL@%
  20648. %@NL@%
  20649. where %@AI@%filename%@AE@% is the name of the source file in which the error was
  20650. encountered; %@AI@%line-number%@AE@% is the line number at which the compiler detected
  20651. the error; %@AI@%diagnostic%@AE@% is either "error" or "warning"; %@AI@%number%@AE@% is a unique
  20652. four-digit number (preceded by a %@AB@%C%@AE@%) that identifies the error or warning;
  20653. %@AI@%message%@AE@% is an explanatory message.  %@NL@%
  20654. %@NL@%
  20655. %@NL@%
  20656. %@2@%%@CR:C6A-C0004   @%%@AB@%C.2  Environment%@AE@%%@EH@%%@NL@%
  20657. %@NL@%
  20658. %@NL@%
  20659. %@3@%%@CR:C6A-C0005   @%%@AB@%C.2.1  Arguments to main%@AE@%%@EH@%%@NL@%
  20660. %@NL@%
  20661. %@AB@%The semantics of the arguments to main (2.1.2.2)%@AE@%  %@NL@%
  20662. %@NL@%
  20663. In Microsoft C, the function called at program start-up is called %@AB@%main%@AE@%.
  20664. There is no prototype declared for %@AB@%main%@AE@%, and it can be defined with zero,
  20665. two, or three parameters:  %@NL@%
  20666. %@NL@%
  20667. %@AS@%  int main( void )
  20668. %@AS@%  int main( int argc, char *argv[] )
  20669. %@AS@%  int main( int argc, char *argv[], char *envp[] )%@AE@%%@NL@%
  20670. %@NL@%
  20671. The third line above, where %@AB@%main %@AE@%accepts three parameters, is a Microsoft
  20672. extension to the ANSI Standard. The third parameter, %@AB@%envp%@AE@%, is an array of
  20673. pointers to environment variables. The %@AB@%envp %@AE@%array is terminated by a null
  20674. pointer. See on-line help for more information about %@AB@%main %@AE@%and %@AB@%envp%@AE@%.  %@NL@%
  20675. %@NL@%
  20676. The variable %@AB@%argc%@AE@% never holds a negative value.  %@NL@%
  20677. %@NL@%
  20678. The array of strings ends with %@AB@%argv[argc]%@AE@%, which contains a null pointer.  %@NL@%
  20679. %@NL@%
  20680. All elements of the %@AB@%argv %@AE@%array are pointers to strings.  %@NL@%
  20681. %@NL@%
  20682. A program invoked with no command-line arguments will receive a value of one
  20683. for %@AB@%argc%@AE@%, as the name of the executable file is placed in %@AB@%argv[0]%@AE@%. (In DOS
  20684. versions prior to 3.0, the executable file name is not available. The letter
  20685. "C" is placed in %@AB@%argv[0]%@AE@%.) Strings pointed to by %@AB@%argv[1] %@AE@%through %@AB@%argv[argc -
  20686. %@AB@%1] %@AE@%represent program parameters.  %@NL@%
  20687. %@NL@%
  20688. The parameters %@AB@%argc %@AE@%and %@AB@%argv %@AE@%are modifiable and retain their last-stored
  20689. values between program start-up and program termination.  %@NL@%
  20690. %@NL@%
  20691. %@NL@%
  20692. %@3@%%@CR:C6A-C0006   @%%@AB@%C.2.2  Interactive Devices%@AE@%%@EH@%%@NL@%
  20693. %@NL@%
  20694. %@AB@%What constitutes an interactive device (2.1.2.3)%@AE@%  %@NL@%
  20695. %@NL@%
  20696. Microsoft C defines the keyboard and the display as interactive devices.  %@NL@%
  20697. %@NL@%
  20698. %@NL@%
  20699. %@2@%%@CR:C6A-C0007   @%%@AB@%C.3  Identifiers%@AE@%%@EH@%%@NL@%
  20700. %@NL@%
  20701. %@NL@%
  20702. %@3@%%@CR:C6A-C0008   @%%@AB@%C.3.1  Significant Characters without External Linkage%@AE@%%@EH@%%@NL@%
  20703. %@NL@%
  20704. %@AB@%The number of significant characters without external linkage (3.1.2)%@AE@%  %@NL@%
  20705. %@NL@%
  20706. Identifiers are significant to 31 characters. The compiler does not restrict
  20707. the number of characters you can use in an identifier; it simply ignores any
  20708. characters beyond the limit.  %@NL@%
  20709. %@NL@%
  20710. %@NL@%
  20711. %@3@%%@CR:C6A-C0009   @%%@AB@%C.3.2  Significant Characters with External Linkage%@AE@%%@EH@%%@NL@%
  20712. %@NL@%
  20713. %@AB@%The number of significant characters with external linkage (3.1.2)%@AE@%  %@NL@%
  20714. %@NL@%
  20715. Identifiers declared %@AB@%extern %@AE@%in programs compiled with Microsoft C are
  20716. significant to 31 characters. You can modify this default to a smaller
  20717. number using the /H (restrict length of external names) option. See on-line
  20718. help for more information on the syntax of the /H option.  %@NL@%
  20719. %@NL@%
  20720. %@NL@%
  20721. %@3@%%@CR:C6A-C0010   @%%@AB@%C.3.3  Upper- and Lowercase%@AE@%%@EH@%%@NL@%
  20722. %@NL@%
  20723. %@AB@%Whether case distinctions are significant (3.1.2)%@AE@%  %@NL@%
  20724. %@NL@%
  20725. Microsoft C treats identifiers within a compilation unit as case sensitive.
  20726. Externally linked identifiers may or may not be case sensitive, depending on
  20727. whether you use /NOIGNORECASE option when you invoke the linker. The default
  20728. for the linker is to ignore case, making externally linked identifiers case
  20729. insensitive.  %@NL@%
  20730. %@NL@%
  20731. Thus, symbols in source files are sensitive to case. By default, symbols in
  20732. object files are not.  %@NL@%
  20733. %@NL@%
  20734. Two CL command-line options affect case sensitivity:  %@NL@%
  20735. %@NL@%
  20736. %@NL@%
  20737.   1.  The /Gc (generate Pascal-style function calls) command-line option
  20738.       converts all external identifiers (including function names) to
  20739.       uppercase.%@NL@%
  20740. %@NL@%
  20741. %@STUB@%      The %@AB@%_pascal%@AE@% declarator performs the same operation on a
  20742.       function-byfunction basis.%@NL@%
  20743. %@NL@%
  20744.   2.  The /Zc (compile case insensitive) converts all identifiers (excluding
  20745.       function names) to uppercase.%@NL@%
  20746. %@NL@%
  20747. %@NL@%
  20748. %@NL@%
  20749. %@2@%%@CR:C6A-C0011   @%%@AB@%C.4  Characters%@AE@%%@EH@%%@NL@%
  20750. %@NL@%
  20751. %@NL@%
  20752. %@3@%%@CR:C6A-C0012   @%%@AB@%C.4.1  The ASCII Character Set%@AE@%%@EH@%%@NL@%
  20753. %@NL@%
  20754. %@AB@%Members of source and execution character sets (2.2.1)%@AE@%  %@NL@%
  20755. %@NL@%
  20756. The source character set is the set of legal characters that can appear in
  20757. source files. For Microsoft C, the source character set is the standard
  20758. ASCII character set. Figure C.1 contains an ASCII table.  %@NL@%
  20759. %@NL@%
  20760. ────────────────────────────────────────────────────────────────────────────%@NL@%
  20761. %@AU@%WARNING%@AE@%%@NL@%
  20762. %@NL@%
  20763. Because keyboard and console drivers can remap the character set, programs
  20764. intended for international distribution should check the country code.%@NL@%
  20765. ────────────────────────────────────────────────────────────────────────────%@NL@%
  20766. %@NL@%
  20767. %@NL@%
  20768. %@3@%%@CR:C6A-C0013   @%%@AB@%C.4.2  Multibyte Characters%@AE@%%@EH@%%@NL@%
  20769. %@NL@%
  20770. %@AB@%Shift states for multibyte characters (2.2.1)%@AE@%  %@NL@%
  20771. %@NL@%
  20772. Multibyte characters are used by some implementations to represent
  20773. foreignlanguage characters not represented in the base character set.
  20774. Microsoft C 6.0 does not support multibyte characters.  %@NL@%
  20775. %@NL@%
  20776. %@NL@%
  20777. %@3@%%@CR:C6A-C0014   @%%@AB@%C.4.3  Bits per Character%@AE@%%@EH@%%@NL@%
  20778. %@NL@%
  20779. %@AB@%Number of bits in a character (2.2.4.2)%@AE@%  %@NL@%
  20780. %@NL@%
  20781. The number of bits in a character is represented by the manifest constant
  20782. %@AB@%CHAR_BIT%@AE@%. The LIMITS.H file defines %@AB@%CHAR_BIT%@AE@% as 8.  %@NL@%
  20783. %@NL@%
  20784. %@NL@%
  20785. %@3@%%@CR:C6A-C0015   @%%@AB@%C.4.4  Character Sets%@AE@%%@EH@%%@NL@%
  20786. %@NL@%
  20787. %@AB@%Mapping members of the source character set (3.1.3.4)%@AE@%  %@NL@%
  20788. %@NL@%
  20789. The source character set and execution character set include the ANSI ASCII
  20790. characters listed in Table C.1. Escape sequences are also shown in Table
  20791. C.1.  %@NL@%
  20792. %@NL@%
  20793. %@AB@%Table   %@AB@%C.1%@AE@%%@AE@%
  20794.  
  20795. %@TH:  13   657 02 17 18 41 @%
  20796. Escape Sequence  Character         ASCII Value
  20797. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20798. \a               Alert/bell        7
  20799. \b               Backspace         8
  20800. \f               Form feed         12
  20801. \n               Newline           10
  20802. \r               Carriage return   13
  20803. \t               Horizontal tab    9
  20804. \v               Vertical tab      11
  20805. \"               Double quotation  34
  20806. \%@AS@%'%@AE@%               Single quotation  39
  20807. \\               Backslash         92
  20808. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20809. %@TE:  13   657 02 17 18 41 @%
  20810.  
  20811. %@NL@%
  20812. %@3@%%@CR:C6A-C0016   @%%@AB@%C.4.5  Unrepresented Character Constants%@AE@%%@EH@%%@NL@%
  20813. %@NL@%
  20814. %@AB@%The value of an integer character constant that contains a character or
  20815. %@AB@%escape sequence not represented in the basic execution character set or the
  20816. %@AB@%extended character set for a wide character constant (3.1.3.4)%@AE@%  %@NL@%
  20817. %@NL@%
  20818. Microsoft C does not support wide characters.  %@NL@%
  20819. %@NL@%
  20820. %@NL@%
  20821. %@3@%%@CR:C6A-C0017   @%%@AB@%C.4.6  Wide Characters%@AE@%%@EH@%%@NL@%
  20822. %@NL@%
  20823. %@AB@%The value of an integer character constant that contains more than one
  20824. %@AB@%character or a wide character constant that contains more than one multibyte
  20825. %@AB@%character (3.1.3.4)%@AE@%  %@NL@%
  20826. %@NL@%
  20827. Microsoft C does not support wide characters or multibyte characters.  %@NL@%
  20828. %@NL@%
  20829. %@NL@%
  20830. %@3@%%@CR:C6A-C0018   @%%@AB@%C.4.7  Converting Multibyte Characters%@AE@%%@EH@%%@NL@%
  20831. %@NL@%
  20832. %@AB@%The current locale used to convert multibyte characters into corresponding
  20833. %@AB@%wide characters (codes) for a wide character constant (3.1.3.4)  %@AE@%%@NL@%
  20834. %@NL@%
  20835. Microsoft C does not support multibyte characters.  %@NL@%
  20836. %@NL@%
  20837. %@NL@%
  20838. %@3@%%@CR:C6A-C0019   @%%@AB@%C.4.8  Range of char Values%@AE@%%@EH@%%@NL@%
  20839. %@NL@%
  20840. %@AB@%Whether a "plain" char has the same range of values as a signed char or an
  20841. %@AB@%unsigned char (3.2.1.1)%@AE@%  %@NL@%
  20842. %@NL@%
  20843. All character values range from 0x00 to 0xFF, signed or unsigned. If a %@AB@%char%@AE@%
  20844. is not explicitly marked as %@AB@%signed%@AE@% or %@AB@%unsigned%@AE@%, it defaults to the %@AB@%signed%@AE@%
  20845. type.  %@NL@%
  20846. %@NL@%
  20847. The CL option /J changes the default from %@AB@%signed%@AE@% to %@AB@%unsigned%@AE@%.  %@NL@%
  20848. %@NL@%
  20849. %@NL@%
  20850. %@2@%%@CR:C6A-C0020   @%%@AB@%C.5  Integers%@AE@%%@EH@%%@NL@%
  20851. %@NL@%
  20852. %@NL@%
  20853. %@3@%%@CR:C6A-C0021   @%%@AB@%C.5.1  Range of Integer Values%@AE@%%@EH@%%@NL@%
  20854. %@NL@%
  20855. %@AB@%The representations and sets of values of the various types of integers
  20856. %@AB@%(3.1.2.5)%@AE@%  %@NL@%
  20857. %@NL@%
  20858. Short integers contain 16 bits (two bytes). Long integers contain 32 bits
  20859. (four bytes). Signed integers are represented in two's-complement form. The
  20860. mostsignificant bit holds the sign: 1 for negative, 0 for positive and zero.
  20861. The values are listed below:  %@NL@%
  20862. %@NL@%
  20863. %@AB@%Type%@AE@%                              %@AB@%Minimum and Maximum%@AE@%
  20864. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  20865. %@AB@%unsigned short%@AE@%                    0 to 65535
  20866.  
  20867. %@AB@%signed short%@AE@%                      -32768 to 32767
  20868.  
  20869. %@AB@%unsigned long%@AE@%                     0 to 4294967295
  20870.  
  20871. %@AB@%signed long%@AE@%                       -2147483648 to 2147483647
  20872.  
  20873. %@NL@%
  20874. %@3@%%@CR:C6A-C0022   @%%@AB@%C.5.2  Demotion of Integers%@AE@%%@EH@%%@NL@%
  20875. %@NL@%
  20876. %@AB@%The result of converting an integer to a shorter signed integer, or the
  20877. %@AB@%result of converting an unsigned integer to a signed integer of equal
  20878. %@AB@%length, if the value cannot be represented (3.2.1.2)%@AE@%  %@NL@%
  20879. %@NL@%
  20880. When a %@AB@%long%@AE@% integer is cast to a %@AB@%short%@AE@%, or a %@AB@%short%@AE@% is cast to a %@AB@%char%@AE@%, the
  20881. least significant bytes are retained.  %@NL@%
  20882. %@NL@%
  20883. For example, this line  %@NL@%
  20884. %@NL@%
  20885. %@AS@%  short x = (short)0x12345678L;%@AE@%%@NL@%
  20886. %@NL@%
  20887. assigns the value 0x5678 to %@AS@% x%@AE@%, and this line  %@NL@%
  20888. %@NL@%
  20889. %@AS@%  char y = (char)0x1234;%@AE@%%@NL@%
  20890. %@NL@%
  20891. assigns the value 0x34 to %@AS@% y%@AE@%.  %@NL@%
  20892. %@NL@%
  20893. When signed variables are converted to unsigned and vice versa, the bit
  20894. patterns remain the same. For example, casting -2 (0xFE) to an unsigned
  20895. value yields 254 (also 0xFE).  %@NL@%
  20896. %@NL@%
  20897. %@NL@%
  20898. %@3@%%@CR:C6A-C0023   @%%@AB@%C.5.3  Signed Bitwise Operations%@AE@%%@EH@%%@NL@%
  20899. %@NL@%
  20900. %@AB@%The results of bitwise operations on signed integers (3.3)%@AE@%  %@NL@%
  20901. %@NL@%
  20902. Bitwise operations on signed integers work the same as bitwise operations on
  20903. unsigned integers. For example, %@AS@% -16 & 99 %@AE@% can be expressed in binary as  %@NL@%
  20904. %@NL@%
  20905. %@AS@%  11111111 11110000
  20906. %@AS@%  & 00000000 01100011
  20907. %@AS@%    -----------------
  20908. %@AS@%    00000000 01100000%@AE@%%@NL@%
  20909. %@NL@%
  20910. The result of the bitwise AND is 96.  %@NL@%
  20911. %@NL@%
  20912. %@NL@%
  20913. %@3@%%@CR:C6A-C0024   @%%@AB@%C.5.4  Remainders%@AE@%%@EH@%%@NL@%
  20914. %@NL@%
  20915. %@AB@%The sign of the remainder on integer division (3.3.5)%@AE@%  %@NL@%
  20916. %@NL@%
  20917. The sign of the remainder is the same as the sign of the dividend. For
  20918. example,  %@NL@%
  20919. %@NL@%
  20920. %@AS@%  50 / -6 == -8
  20921. %@AS@%   50 % -6 ==  2
  20922. %@AS@%  -50 /  6 == -8
  20923. %@AS@%  -50 %  6 == -2%@AE@%%@NL@%
  20924. %@NL@%
  20925. %@NL@%
  20926. %@3@%%@CR:C6A-C0025   @%%@AB@%C.5.5  Right Shifts%@AE@%%@EH@%%@NL@%
  20927. %@NL@%
  20928. %@AB@%The result of a right shift of a negative-value signed integral type
  20929. %@AB@%(3.3.7)%@AE@%  %@NL@%
  20930. %@NL@%
  20931. Shifting a negative value to the right yields half the absolute value,
  20932. rounded down. For example, -253 (binary 11111111 00000011) shifted right one
  20933. bit produces -127 (binary 11111111 10000001). A %@AI@%positive%@AE@% 253 shifts right to
  20934. produce +126.  %@NL@%
  20935. %@NL@%
  20936. Right shifts preserve the sign bit. When a signed integer shifts right, the
  20937. mostsignificant bit remains set. When an unsigned integer shifts right, the
  20938. mostsignificant bit is cleared. Thus, if 0xF000 is signed, a right shift
  20939. produces 0xF800. If 0xF000 is unsigned, the result is 0x7800.  %@NL@%
  20940. %@NL@%
  20941. Shifting a positive number right sixteen times produces 0x0000. Shifting a
  20942. negative number right sixteen times produces 0xFFFF.  %@NL@%
  20943. %@NL@%
  20944. %@NL@%
  20945. %@2@%%@CR:C6A-C0026   @%%@AB@%C.6  Floating-Point Math%@AE@%%@EH@%%@NL@%
  20946. %@NL@%
  20947. %@NL@%
  20948. %@3@%%@CR:C6A-C0027   @%%@AB@%C.6.1  Values%@AE@%%@EH@%%@NL@%
  20949. %@NL@%
  20950. %@AB@%The representations and sets of values of the various types of
  20951. %@AB@%floating-point numbers (3.1.2.5)%@AE@%  %@NL@%
  20952. %@NL@%
  20953. The %@AB@%float%@AE@% type contains 32 bits: 1 for the sign, 8 for the exponent, and 23
  20954. for the mantissa. Its range is +/- 3.4E38 with at least 7 digits of
  20955. precision.  %@NL@%
  20956. %@NL@%
  20957. The %@AB@%double%@AE@% type contains 64 bits: 1 for the sign, 11 for the exponent, and
  20958. 52 for the mantissa. Its range is +/- 1.7E308 with at least 15 digits of
  20959. precision.  %@NL@%
  20960. %@NL@%
  20961. The %@AB@%long double%@AE@% type is new to Version 6.0 of Microsoft C. It contains 80
  20962. bits: 1 for the sign, 15 for the exponent, and 64 for the mantissa. Its
  20963. range is +/- 1.2E4932 with at least 17 digits of precision.  %@NL@%
  20964. %@NL@%
  20965. %@NL@%
  20966. %@3@%%@CR:C6A-C0028   @%%@AB@%C.6.2  Casting Integers to Floating-Point Values%@AE@%%@EH@%%@NL@%
  20967. %@NL@%
  20968. %@AB@%The direction of truncation when an integral number is converted to a
  20969. %@AB@%floating-point number that cannot exactly represent the original value
  20970. %@AB@%(3.2.1.3)%@AE@%  %@NL@%
  20971. %@NL@%
  20972. When an integral number is cast to a floating-point value that cannot
  20973. exactly represent the value, the value is rounded (up or down) to the
  20974. nearest suitable value.  %@NL@%
  20975. %@NL@%
  20976. For example, casting an %@AB@%unsigned long%@AE@% (with 32 bits of precision) to a %@AB@%float%@AE@%
  20977. (whose mantissa has 23 bits of precision) rounds the number to the nearest
  20978. multiple of 256. The %@AB@%long%@AE@% values 4294966913 - 4294967167 are all rounded to
  20979. the %@AB@%float%@AE@% value 4294967040.  %@NL@%
  20980. %@NL@%
  20981. %@NL@%
  20982. %@3@%%@CR:C6A-C0029   @%%@AB@%C.6.3  Truncation of Floating-Point Values%@AE@%%@EH@%%@NL@%
  20983. %@NL@%
  20984. %@AB@%The direction of truncation or rounding when a floating-point number is
  20985. %@AB@%converted to a narrower floating-point number (3.2.1.4)%@AE@%  %@NL@%
  20986. %@NL@%
  20987. When an underflow occurs, the value of a floating-point variable is rounded
  20988. down to zero. An overflow causes a run-time math error.  %@NL@%
  20989. %@NL@%
  20990. %@NL@%
  20991. %@2@%%@CR:C6A-C0030   @%%@AB@%C.7  Arrays and Pointers%@AE@%%@EH@%%@NL@%
  20992. %@NL@%
  20993. %@NL@%
  20994. %@3@%%@CR:C6A-C0031   @%%@AB@%C.7.1  Largest Array Size%@AE@%%@EH@%%@NL@%
  20995. %@NL@%
  20996. %@AB@%The type of integer required to hold the maximum size of an array─that is,
  20997. %@AB@%the size of size_t (3.3.3.4, 4.1.1)%@AE@%  %@NL@%
  20998. %@NL@%
  20999. The %@AB@%size_t%@AE@% typedef is an %@AB@%unsigned short%@AE@%, with the range 0x0000 to 0xFFFF.
  21000. Huge arrays can exceed this limit if they contain more than 65,535 elements.
  21001. Arithmetic operations on huge arrays should therefore cast %@AB@%size_t%@AE@% and the
  21002. results of an arithmetic operations on pointers to %@AB@%unsigned long%@AE@%.  %@NL@%
  21003. %@NL@%
  21004. %@NL@%
  21005. %@3@%%@CR:C6A-C0032   @%%@AB@%C.7.2  Casting Pointers%@AE@%%@EH@%%@NL@%
  21006. %@NL@%
  21007. %@AB@%The result of casting a pointer to an integer or vice versa (3.3.4)%@AE@%  %@NL@%
  21008. %@NL@%
  21009. Near pointers are the same size as short integers; casting near to short (or
  21010. short to near) has no immediate effect on the value.  %@NL@%
  21011. %@NL@%
  21012. Far pointers and huge pointers are the same size as long integers. Casting
  21013. far/huge to long (or long to far/huge) has no immediate effect on the value.
  21014. %@NL@%
  21015. %@NL@%
  21016. When a near pointer is cast to a long, the 16-bit value is "normalized,"
  21017. which means the segment (usually DS) and offset are combined to produce a
  21018. 32-bit memory location.  %@NL@%
  21019. %@NL@%
  21020. When a far or huge pointer is cast to a short, the long value is truncated
  21021. to a short.  %@NL@%
  21022. %@NL@%
  21023. The compiler normalizes based pointers when necessary, unless the based
  21024. pointer is a constant zero, in which case it is assumed to be a null
  21025. pointer. See Chapter 13, "Writing Portable Programs," for more information
  21026. about based pointers.  %@NL@%
  21027. %@NL@%
  21028. %@NL@%
  21029. %@3@%%@CR:C6A-C0033   @%%@AB@%C.7.3  Pointer Subtraction%@AE@%%@EH@%%@NL@%
  21030. %@NL@%
  21031. %@AB@%The type of integer required to hold the difference between two pointers to
  21032. %@AB@%elements of the same array, ptrdiff_t (3.3.6, 4.1.1)%@AE@%  %@NL@%
  21033. %@NL@%
  21034. A %@AB@%ptrdiff_t%@AE@% is a signed integer in the range -32768 to 32767, with one
  21035. exception. Because huge pointers can address more than 64K of memory,
  21036. subtracting one huge pointer from another can yield a result that is a long
  21037. integer. The result of subtracting two huge pointers should be cast to a
  21038. long.  %@NL@%
  21039. %@NL@%
  21040. The compiler normalizes based pointers when necessary. In most cases, based
  21041. pointers are treated as far pointers.  %@NL@%
  21042. %@NL@%
  21043. %@NL@%
  21044. %@2@%%@CR:C6A-C0034   @%%@AB@%C.8  Registers%@AE@%%@EH@%%@NL@%
  21045. %@NL@%
  21046. %@NL@%
  21047. %@3@%%@CR:C6A-C0035   @%%@AB@%C.8.1  Availability of Registers%@AE@%%@EH@%%@NL@%
  21048. %@NL@%
  21049. %@AB@%The extent to which objects can actually be placed in registers by use of
  21050. %@AB@%the register storage-class specifier (3.5.1)%@AE@%  %@NL@%
  21051. %@NL@%
  21052. Two registers, SI and DI, are available in Microsoft C. Register variables
  21053. with a type that has 16 bits may be allocated in these registers.  %@NL@%
  21054. %@NL@%
  21055. %@NL@%
  21056. %@2@%%@CR:C6A-C0036   @%%@AB@%C.9  Structures, Unions, Enumerations, and Bit Fields%@AE@%%@EH@%%@NL@%
  21057. %@NL@%
  21058. %@NL@%
  21059. %@3@%%@CR:C6A-C0037   @%%@AB@%C.9.1  Improper Access to a Union%@AE@%%@EH@%%@NL@%
  21060. %@NL@%
  21061. %@AB@%A member of a union object is accessed using a member of a different type
  21062. %@AB@%(3.3.2.3)%@AE@%  %@NL@%
  21063. %@NL@%
  21064. If a union of two types is declared and one value is stored, but the union
  21065. is accessed with the other type, the results are unreliable.  %@NL@%
  21066. %@NL@%
  21067. For example, a union of %@AB@%float%@AE@% and %@AB@%int%@AE@% is declared. A %@AB@%float%@AE@% value is stored,
  21068. but the program later accesses the value as an %@AB@%int%@AE@%. In such a situation, the
  21069. value would depend on the internal storage of %@AB@%float%@AE@% values. The integer
  21070. value would not be reliable.  %@NL@%
  21071. %@NL@%
  21072. %@NL@%
  21073. %@3@%%@CR:C6A-C0038   @%%@AB@%C.9.2  Sign of Bit Fields%@AE@%%@EH@%%@NL@%
  21074. %@NL@%
  21075. %@AB@%Whether a "plain" int field is treated as a signed int bit field or as an
  21076. %@AB@%unsigned int bit field (3.5.2.1)%@AE@%  %@NL@%
  21077. %@NL@%
  21078. Bit fields can be signed or unsigned. Plain bit fields are treated as
  21079. signed.  %@NL@%
  21080. %@NL@%
  21081. %@NL@%
  21082. %@3@%%@CR:C6A-C0039   @%%@AB@%C.9.3  Storage of Bit Fields%@AE@%%@EH@%%@NL@%
  21083. %@NL@%
  21084. %@AB@%The order of allocation of bit fields within an int (3.5.2.1)%@AE@%  %@NL@%
  21085. %@NL@%
  21086. Bit fields are allocated within a 16-bit integer from least-significant to
  21087. mostsignificant bit. In the following code,  %@NL@%
  21088. %@NL@%
  21089. %@AS@%  struct mybitfields
  21090. %@AS@%  {
  21091. %@AS@%     unsigned a : 4;
  21092. %@AS@%     unsigned b : 5;
  21093. %@AS@%     unsigned c : 7;
  21094. %@AS@%  } test;
  21095. %@AS@%  
  21096. %@AS@%  void main( void )
  21097. %@AS@%  {
  21098. %@AS@%     test.a = 2;
  21099. %@AS@%     test.b = 31;
  21100. %@AS@%     test.c = 0;
  21101. %@AS@%  }%@AE@%%@NL@%
  21102. %@NL@%
  21103. the bits would be arranged as follows:  %@NL@%
  21104. %@NL@%
  21105. %@AS@%  00000001 11110010
  21106. %@AS@%  cccccccb bbbbaaaa%@AE@%%@NL@%
  21107. %@NL@%
  21108. Since the 80%@AI@%x%@AE@%86 processors store the low byte of integer values before the
  21109. high byte, the integer 0x01F2 above would be stored in physical memory as
  21110. 0xF2 followed by 0x01.  %@NL@%
  21111. %@NL@%
  21112. %@NL@%
  21113. %@3@%%@CR:C6A-C0040   @%%@AB@%C.9.4  Alignment of Bit Fields%@AE@%%@EH@%%@NL@%
  21114. %@NL@%
  21115. %@AB@%Whether a bit field can straddle a storage-unit boundary (3.5.2.1)%@AE@%  %@NL@%
  21116. %@NL@%
  21117. Bit fields default to size %@AB@%short%@AE@%, which can cross a byte boundary (see
  21118. Section C.9.3 above) but not a 16-bit boundary. If the size and location of
  21119. a bit field would cause it to overflow the current integer, the field is
  21120. moved to the beginning of the next available integer.  %@NL@%
  21121. %@NL@%
  21122. If a bit field is declared as a %@AB@%long%@AE@%, it can hold up to 32 bits.  %@NL@%
  21123. %@NL@%
  21124. In either case, an individual field cannot cross a 16- or 32-bit boundary.  %@NL@%
  21125. %@NL@%
  21126. %@NL@%
  21127. %@3@%%@CR:C6A-C0041   @%%@AB@%C.9.5  The enum Type%@AE@%%@EH@%%@NL@%
  21128. %@NL@%
  21129. %@AB@%The integer type chosen to represent the values of an enumeration type
  21130. %@AB@%(3.5.2.2)%@AE@%  %@NL@%
  21131. %@NL@%
  21132. A variable declared as %@AB@%enum%@AE@% is a signed short integer.  %@NL@%
  21133. %@NL@%
  21134. %@NL@%
  21135. %@2@%%@CR:C6A-C0042   @%%@AB@%C.10  Qualifiers%@AE@%%@EH@%%@NL@%
  21136. %@NL@%
  21137. %@NL@%
  21138. %@3@%%@CR:C6A-C0043   @%%@AB@%C.10.1  Access to Volatile Objects%@AE@%%@EH@%%@NL@%
  21139. %@NL@%
  21140. %@AB@%What constitutes an access to an object that has volatile-qualified type
  21141. %@AB@%(3.5.3)%@AE@%  %@NL@%
  21142. %@NL@%
  21143. Any reference to a volatile-qualified type is an access.  %@NL@%
  21144. %@NL@%
  21145. %@NL@%
  21146. %@2@%%@CR:C6A-C0044   @%%@AB@%C.11  Declarators%@AE@%%@EH@%%@NL@%
  21147. %@NL@%
  21148. %@NL@%
  21149. %@3@%%@CR:C6A-C0045   @%%@AB@%C.11.1  Maximum Number%@AE@%%@EH@%%@NL@%
  21150. %@NL@%
  21151. %@AB@%The maximum number of declarators that can modify an arithmetic, structure,
  21152. %@AB@%or union type (3.5.4)%@AE@%  %@NL@%
  21153. %@NL@%
  21154. Microsoft C does not limit the number of declarators. The number is limited
  21155. only by available memory.  %@NL@%
  21156. %@NL@%
  21157. %@NL@%
  21158. %@2@%%@CR:C6A-C0046   @%%@AB@%C.12  Statements%@AE@%%@EH@%%@NL@%
  21159. %@NL@%
  21160. %@NL@%
  21161. %@3@%%@CR:C6A-C0047   @%%@AB@%C.12.1  Limits on Switch Statements%@AE@%%@EH@%%@NL@%
  21162. %@NL@%
  21163. %@AB@%The maximum number of case values in a switch statement (3.6.4.2)%@AE@%  %@NL@%
  21164. %@NL@%
  21165. Microsoft C does not limit the number of %@AB@%case%@AE@% values in a %@AB@%switch%@AE@% statement.
  21166. The number is limited only by available memory.  %@NL@%
  21167. %@NL@%
  21168. %@NL@%
  21169. %@2@%%@CR:C6A-C0048   @%%@AB@%C.13  Preprocessing Directives%@AE@%%@EH@%%@NL@%
  21170. %@NL@%
  21171. %@NL@%
  21172. %@3@%%@CR:C6A-C0049   @%%@AB@%C.13.1  Character Constants and Conditional Inclusion%@AE@%%@EH@%%@NL@%
  21173. %@NL@%
  21174. %@AB@%Whether the value of a single-character character constant in a constant
  21175. %@AB@%expression that controls conditional inclusion matches the value of the same
  21176. %@AB@%character constant in the execution character set. Whether such a character
  21177. %@AB@%constant can have a negative value (3.8.1)%@AE@%  %@NL@%
  21178. %@NL@%
  21179. The character set used in preprocessor statements is the same as the
  21180. execution character set. The preprocessor recognizes negative character
  21181. values.  %@NL@%
  21182. %@NL@%
  21183. %@NL@%
  21184. %@3@%%@CR:C6A-C0050   @%%@AB@%C.13.2  Including Bracketed File Names%@AE@%%@EH@%%@NL@%
  21185. %@NL@%
  21186. %@AB@%The method for locating includable source files (3.8.2)%@AE@%  %@NL@%
  21187. %@NL@%
  21188. The preprocessor first searches the directories specified by the CL option
  21189. /I. If the /I option is not present or if it fails, the preprocessor uses
  21190. the INCLUDE environment variable to find any include files within angle
  21191. brackets. If more than one directory appears as part of the /I option or
  21192. within the INCLUDE variable, the preprocessor searches them in the order
  21193. they appear.  %@NL@%
  21194. %@NL@%
  21195. For example, the command  %@NL@%
  21196. %@NL@%
  21197. %@AS@%  CL /ID:\MSC\INCLUDE MYPROG.C%@AE@%%@NL@%
  21198. %@NL@%
  21199. causes the preprocessor to search the directory D:\MSC\INCLUDE for include
  21200. files such as STDIO.H.  %@NL@%
  21201. %@NL@%
  21202. The commands  %@NL@%
  21203. %@NL@%
  21204. %@AS@%  SET INCLUDE = D:\MSC\INCLUDE
  21205. %@AS@%  CL MYPROG.C%@AE@%%@NL@%
  21206. %@NL@%
  21207. have a similar effect.  %@NL@%
  21208. %@NL@%
  21209. If both sets of searches fail, a fatal error is generated.  %@NL@%
  21210. %@NL@%
  21211. %@NL@%
  21212. %@3@%%@CR:C6A-C0051   @%%@AB@%C.13.3  Including Quoted File Names%@AE@%%@EH@%%@NL@%
  21213. %@NL@%
  21214. %@AB@%The support for quoted names for includable source files (3.8.2)%@AE@%  %@NL@%
  21215. %@NL@%
  21216. If the file name is fully specified, with a path that includes a colon (for
  21217. example, F:\C6\SPECIAL\INCL\ORANGE.H), the preprocessor follows the path.  %@NL@%
  21218. %@NL@%
  21219. If the file name is not fully specified, the preprocessor searches the
  21220. directory of the file that included it. If the file is not found there, the
  21221. preprocessor searches the parent directory, the parent's parent, and so on,
  21222. terminating with the root directory.  %@NL@%
  21223. %@NL@%
  21224. If the include file is not found in any of those directories, the rules for
  21225. bracketed file names apply.  %@NL@%
  21226. %@NL@%
  21227. %@NL@%
  21228. %@3@%%@CR:C6A-C0052   @%%@AB@%C.13.4  Character Sequences%@AE@%%@EH@%%@NL@%
  21229. %@NL@%
  21230. %@AB@%The mapping of source file character sequences (3.8.2)%@AE@%  %@NL@%
  21231. %@NL@%
  21232. Preprocessor statements use the same character set as source file statements
  21233. with the exception that escape sequences are not supported.  %@NL@%
  21234. %@NL@%
  21235. Thus, to specify a path for an include file, use only one backslash:  %@NL@%
  21236. %@NL@%
  21237. %@AS@%  #include "path1\path2\myfile"%@AE@%%@NL@%
  21238. %@NL@%
  21239. Within source code, two backslashes are necessary:  %@NL@%
  21240. %@NL@%
  21241. %@AS@%  fil = fopen( "path1\\path2\\myfile", "rt" );%@AE@%%@NL@%
  21242. %@NL@%
  21243. %@NL@%
  21244. %@3@%%@CR:C6A-C0053   @%%@AB@%C.13.5  Pragmas%@AE@%%@EH@%%@NL@%
  21245. %@NL@%
  21246. %@AB@%The behavior on each recognized #pragma directive (3.8.6)%@AE@%  %@NL@%
  21247. %@NL@%
  21248. The following pragmas are defined in the %@AI@%Microsoft C Reference%@AE@%:  %@NL@%
  21249. %@NL@%
  21250. %@AB@%#pragma alloc_text%@AE@%                %@AB@%#pragma optimize%@AE@%
  21251. %@AB@%#pragma check_pointer%@AE@%             %@AB@%#pragma pack%@AE@%
  21252. %@AB@%#pragma check_stack%@AE@%               %@AB@%#pragma page%@AE@%
  21253. %@AB@%#pragma comment%@AE@%                   %@AB@%#pragma pagesize%@AE@%
  21254. %@AB@%#pragma function%@AE@%                  %@AB@%#pragma same_seg%@AE@%
  21255. %@AB@%#pragma intrinsic%@AE@%                 %@AB@%#pragma skip%@AE@%
  21256. %@AB@%#pragma linesize%@AE@%                  %@AB@%#pragma subtitle%@AE@%
  21257. %@AB@%#pragma loop_opt%@AE@%                  %@AB@%#pragma title%@AE@%
  21258. %@AB@%#pragma message%@AE@%                   
  21259.  
  21260. %@NL@%
  21261. %@3@%%@CR:C6A-C0054   @%%@AB@%C.13.6  Default Date and Time%@AE@%%@EH@%%@NL@%
  21262. %@NL@%
  21263. %@AB@%The definitions for _DATE_ and _TIME_ when, respectively, the date and time
  21264. %@AB@%of translation are not available (3.8.8)%@AE@%  %@NL@%
  21265. %@NL@%
  21266. When a hardware clock is not accessible, the default values for _DATE_ and
  21267. _TIME_ are Friday, May 3, 1957 and 5:00 PM.  %@NL@%
  21268. %@NL@%
  21269. %@NL@%
  21270. %@2@%%@CR:C6A-C0055   @%%@AB@%C.14  Library Functions%@AE@%%@EH@%%@NL@%
  21271. %@NL@%
  21272. %@NL@%
  21273. %@3@%%@CR:C6A-C0056   @%%@AB@%C.14.1  NULL Macro%@AE@%%@EH@%%@NL@%
  21274. %@NL@%
  21275. %@AB@%The null pointer constant to which the macro NULL expands (4.1.5)%@AE@%  %@NL@%
  21276. %@NL@%
  21277. Several include files define the NULL macro as %@AS@% ((void *)0)%@AE@%.  %@NL@%
  21278. %@NL@%
  21279. %@NL@%
  21280. %@3@%%@CR:C6A-C0057   @%%@AB@%C.14.2  Diagnostic Printed by the assert Function%@AE@%%@EH@%%@NL@%
  21281. %@NL@%
  21282. %@AB@%The diagnostic printed by and the termination behavior of the assert
  21283. %@AB@%function (4.2)%@AE@%  %@NL@%
  21284. %@NL@%
  21285. The%@AB@% assert %@AE@%function prints a diagnostic message and calls the abort routine
  21286. if the expression is false (0). The diagnostic message has the form  %@NL@%
  21287. %@NL@%
  21288. Assertion failed: [%@AI@%expression%@AE@%], file [%@AI@%filename%@AE@%], line [%@AI@%linenumber%@AE@%]  %@NL@%
  21289. %@NL@%
  21290. where %@AI@%filename %@AE@%is the name of the source file and %@AI@%linenumber %@AE@%is the line
  21291. number of the assertion that failed in the source file. No action is taken
  21292. if%@AI@% expression%@AE@% is true (nonzero).  %@NL@%
  21293. %@NL@%
  21294. %@NL@%
  21295. %@3@%%@CR:C6A-C0058   @%%@AB@%C.14.3  Character Testing%@AE@%%@EH@%%@NL@%
  21296. %@NL@%
  21297. %@AB@%The sets of characters tested for by the isalnum, isalpha, iscntrl, islower,
  21298. %@AB@%isprint, and isupper functions (4.3.1)%@AE@%  %@NL@%
  21299. %@NL@%
  21300. %@AB@%Function%@AE@%                          %@AB@%Tests For%@AE@%
  21301. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  21302. %@AB@%isalnum%@AE@%                           Characters 0 - 9, A-Z, a-z
  21303.                                   ASCII 48-57, 65-90, 97-122
  21304.  
  21305. %@AB@%isalpha%@AE@%                           Characters A-Z, a-z
  21306.                                   ASCII 65-90, 97-122
  21307.  
  21308. %@AB@%iscntrl%@AE@%                           ASCII 0 -31, 127
  21309.  
  21310. %@AB@%islower%@AE@%                           Characters a-z
  21311.                                   ASCII 97-122
  21312.  
  21313. %@AB@%isprint%@AE@%                           Characters A-Z, a-z, 0 - 9, punctuation,
  21314.                                   space
  21315.                                   ASCII 32-126
  21316.  
  21317. %@AB@%isupper%@AE@%                           Characters A-Z
  21318.                                   ASCII 65-90
  21319.  
  21320. %@NL@%
  21321. %@3@%%@CR:C6A-C0059   @%%@AB@%C.14.4  Domain Errors%@AE@%%@EH@%%@NL@%
  21322. %@NL@%
  21323. %@AB@%The values returned by the mathematics functions on domain errors (4.5.1)%@AE@%  %@NL@%
  21324. %@NL@%
  21325. The ERRNO.H file defines the domain error constant EDOM as 33.  %@NL@%
  21326. %@NL@%
  21327. %@NL@%
  21328. %@3@%%@CR:C6A-C0060   @%%@AB@%C.14.5  Underflow of Floating-Point Values%@AE@%%@EH@%%@NL@%
  21329. %@NL@%
  21330. %@AB@%Whether the mathematics functions set the integer expression errno to the
  21331. %@AB@%value of the macro ERANGE on underflow range errors (4.5.1)%@AE@%  %@NL@%
  21332. %@NL@%
  21333. A floating-point underflow does not set the expression %@AB@%errno%@AE@% to ERANGE. When
  21334. a value approaches zero and eventually underflows, the value is set to zero.
  21335. %@NL@%
  21336. %@NL@%
  21337. %@NL@%
  21338. %@3@%%@CR:C6A-C0061   @%%@AB@%C.14.6  The fmod Function%@AE@%%@EH@%%@NL@%
  21339. %@NL@%
  21340. %@AB@%Whether a domain error occurs or zero is returned when the fmod function has
  21341. %@AB@%a second argument of zero (4.5.6.4)%@AE@%  %@NL@%
  21342. %@NL@%
  21343. When the %@AB@%fmod%@AE@% function has a second argument of zero, the function returns
  21344. zero.  %@NL@%
  21345. %@NL@%
  21346. %@NL@%
  21347. %@3@%%@CR:C6A-C0062   @%%@AB@%C.14.7  The signal Function%@AE@%%@EH@%%@NL@%
  21348. %@NL@%
  21349. %@AB@%The set of signals for the signal function (4.7.1.1)%@AE@%  %@NL@%
  21350. %@NL@%
  21351. The first argument passed to %@AB@%signal%@AE@% must be one of the symbolic constants
  21352. listed below. The constants are defined in SIGNAL.H. Also listed is the
  21353. operating mode support for each signal.  %@NL@%
  21354. %@NL@%
  21355. %@AB@%Signal Argument%@AE@%                   %@AB@%Description%@AE@%
  21356. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  21357. SIGABRT                           Abnormal termination (real and protected
  21358.                                   mode).
  21359.  
  21360. SIGBREAK                          CTRL+BREAK signal. Terminates the 
  21361.                                   calling program (protected mode only).
  21362.  
  21363. SIGFPE                            Floating-point error, such as overflow, 
  21364.                                   division by zero, or invalid operation. 
  21365.                                   Terminates the calling program (real and
  21366.                                   protected mode).
  21367.  
  21368. SIGILL                            Illegal instruction. Terminates the 
  21369.                                   calling program (protected mode only).
  21370.  
  21371. SIGINT                            CTRL+C interrupt. Issues INT 23H (real 
  21372.                                   and
  21373.                                   protected mode).
  21374.  
  21375. SIGSEGV                           Illegal storage access. Not generated by
  21376.                                   DOS or OS/2, but supported for ANSI 
  21377.                                   compatibility. Terminates the calling 
  21378.                                   program (real and protected mode).
  21379.  
  21380. SIGTERM                           Termination request sent to the program.
  21381.                                   Not generated by DOS or OS/2, but 
  21382.                                   supported for ANSI compatibility. 
  21383.                                   Terminates the calling program (real and
  21384.                                   protected mode).
  21385.  
  21386. SIGUSR1                           OS/2 process flag A (protected mode 
  21387.                                   only).
  21388.  
  21389. SIGUSR2                           OS/2 process flag B (protected mode 
  21390.                                   only).
  21391.  
  21392. SIGUSR3                           OS/2 process flag C (protected mode 
  21393.                                   only).
  21394.  
  21395. %@NL@%
  21396. %@3@%%@CR:C6A-C0063   @%%@AB@%C.14.8  Default Signals%@AE@%%@EH@%%@NL@%
  21397. %@NL@%
  21398. %@AB@%If the equivalent of signal (sig, SIG_DFL) is not executed prior to the call
  21399. %@AB@%of a signal handler, the blocking of the signal that is performed (4.7.1.1)%@AE@%
  21400. %@NL@%
  21401. %@NL@%
  21402. Signals are set to their default status when a program begins running.  %@NL@%
  21403. %@NL@%
  21404. %@NL@%
  21405. %@3@%%@CR:C6A-C0064   @%%@AB@%C.14.9  The SIGILL Signal%@AE@%%@EH@%%@NL@%
  21406. %@NL@%
  21407. %@AB@%Whether the default handling is reset if the SIGILL signal is received by a
  21408. %@AB@%handler specified to the signal function (4.7.1.1)%@AE@%  %@NL@%
  21409. %@NL@%
  21410. The SIGILL signal applies to OS/2 applications only. When SIGILL is
  21411. received, the signal handling is not reset to the default SIG_DFL.  %@NL@%
  21412. %@NL@%
  21413. %@NL@%
  21414. %@3@%%@CR:C6A-C0065   @%%@AB@%C.14.10  Terminating Newline Characters%@AE@%%@EH@%%@NL@%
  21415. %@NL@%
  21416. %@AB@%Whether the last line of a text stream requires a terminating newline
  21417. %@AB@%character (4.9.2)%@AE@%  %@NL@%
  21418. %@NL@%
  21419. Stream functions recognize either newline or end-of-file as the terminating
  21420. character for a line.  %@NL@%
  21421. %@NL@%
  21422. %@NL@%
  21423. %@3@%%@CR:C6A-C0066   @%%@AB@%C.14.11  Blank Lines%@AE@%%@EH@%%@NL@%
  21424. %@NL@%
  21425. %@AB@%Whether space characters that are written out to a text stream immediately
  21426. %@AB@%before a newline character appear when read in (4.9.2)%@AE@%  %@NL@%
  21427. %@NL@%
  21428. Space characters are preserved.  %@NL@%
  21429. %@NL@%
  21430. %@NL@%
  21431. %@3@%%@CR:C6A-C0067   @%%@AB@%C.14.12  Null Characters%@AE@%%@EH@%%@NL@%
  21432. %@NL@%
  21433. %@AB@%The number of null characters that can be appended to data written to a
  21434. %@AB@%binary stream (4.9.2)%@AE@%  %@NL@%
  21435. %@NL@%
  21436. Any number of null characters can be appended to a binary stream.  %@NL@%
  21437. %@NL@%
  21438. %@NL@%
  21439. %@3@%%@CR:C6A-C0068   @%%@AB@%C.14.13  File Position in Append Mode%@AE@%%@EH@%%@NL@%
  21440. %@NL@%
  21441. %@AB@%Whether the file position indicator of an append mode stream is initially
  21442. %@AB@%positioned at the beginning or end of the file (4.9.3)%@AE@%  %@NL@%
  21443. %@NL@%
  21444. When a file is opened in append mode, the file position indicator initially
  21445. points to the end of the file.  %@NL@%
  21446. %@NL@%
  21447. %@NL@%
  21448. %@3@%%@CR:C6A-C0069   @%%@AB@%C.14.14  Truncation of Text Files%@AE@%%@EH@%%@NL@%
  21449. %@NL@%
  21450. %@AB@%Whether a write on a text stream causes the associated file to be truncated
  21451. %@AB@%beyond that point (4.9.3)%@AE@%  %@NL@%
  21452. %@NL@%
  21453. Writing to a text stream does not truncate the file beyond that point.  %@NL@%
  21454. %@NL@%
  21455. %@NL@%
  21456. %@3@%%@CR:C6A-C0070   @%%@AB@%C.14.15  File Buffering%@AE@%%@EH@%%@NL@%
  21457. %@NL@%
  21458. %@AB@%The characteristics of file buffering (4.9.3)%@AE@%  %@NL@%
  21459. %@NL@%
  21460. Disk files accessed through standard I/O functions are fully buffered. By
  21461. default, the buffer holds 512 bytes. Some of the low-level DOS and BIOS
  21462. functions (all of which are non-ANSI) are unbuffered.  %@NL@%
  21463. %@NL@%
  21464. %@NL@%
  21465. %@3@%%@CR:C6A-C0071   @%%@AB@%C.14.16  Zero-Length Files%@AE@%%@EH@%%@NL@%
  21466. %@NL@%
  21467. %@AB@%Whether a zero-length file actually exists (4.9.3)%@AE@%  %@NL@%
  21468. %@NL@%
  21469. Files with a length of zero are permitted.  %@NL@%
  21470. %@NL@%
  21471. %@NL@%
  21472. %@3@%%@CR:C6A-C0072   @%%@AB@%C.14.17  File Names%@AE@%%@EH@%%@NL@%
  21473. %@NL@%
  21474. %@AB@%The rules for composing valid file names (4.9.3)%@AE@%  %@NL@%
  21475. %@NL@%
  21476. A file specification can include an optional drive letter (always followed
  21477. by a colon), a series of optional directory names (separated by
  21478. backslashes), and a file name.  %@NL@%
  21479. %@NL@%
  21480. File names and directory names can contain up to eight characters followed
  21481. by a period and a three-character extension. Case is ignored. The wild-card
  21482. characters * and ? are not permitted within the name or extension.  %@NL@%
  21483. %@NL@%
  21484. %@NL@%
  21485. %@3@%%@CR:C6A-C0073   @%%@AB@%C.14.18  File Access Limits%@AE@%%@EH@%%@NL@%
  21486. %@NL@%
  21487. %@AB@%Whether the same file can be open multiple times (4.9.3)%@AE@%  %@NL@%
  21488. %@NL@%
  21489. Opening a file that is already open is not permitted.  %@NL@%
  21490. %@NL@%
  21491. %@NL@%
  21492. %@3@%%@CR:C6A-C0074   @%%@AB@%C.14.19  Deleting Open Files%@AE@%%@EH@%%@NL@%
  21493. %@NL@%
  21494. %@AB@%The effect of the remove function on an open file (4.9.4.1)%@AE@%  %@NL@%
  21495. %@NL@%
  21496. The %@AB@%remove%@AE@% function deletes a file, even if the file is open.  %@NL@%
  21497. %@NL@%
  21498. %@NL@%
  21499. %@3@%%@CR:C6A-C0075   @%%@AB@%C.14.20  Renaming with a Name that Exists%@AE@%%@EH@%%@NL@%
  21500. %@NL@%
  21501. %@AB@%The effect if a file with the new name exists prior to a call to the rename
  21502. %@AB@%function (4.9.4.2)%@AE@%  %@NL@%
  21503. %@NL@%
  21504. If you attempt to rename a file using a name that exists, the %@AB@%rename%@AE@%
  21505. function fails and returns an error code.  %@NL@%
  21506. %@NL@%
  21507. %@NL@%
  21508. %@3@%%@CR:C6A-C0076   @%%@AB@%C.14.21  Printing Pointer Values%@AE@%%@EH@%%@NL@%
  21509. %@NL@%
  21510. %@AB@%The output for %p conversion in the fprintf function (4.9.6.1)%@AE@%  %@NL@%
  21511. %@NL@%
  21512. Microsoft C supports three types of pointer conversions: %@AB@%%p %@AE@%(a pointer),%@AB@% %lp%@AE@%
  21513. (a 32-bit far pointer), and %@AB@%%hp %@AE@%(a 16-bit near pointer).  %@NL@%
  21514. %@NL@%
  21515. The %@AB@%fprintf%@AE@% function produces hexadecimal values of the form %@AI@%XXXX%@AE@% (an
  21516. offset) for near pointers or %@AI@%XXXX:XXXX%@AE@% (a segment plus an offset, separated
  21517. by a colon) for far pointers. The output for%@AB@% %p%@AE@% depends on the memory model
  21518. in use.  %@NL@%
  21519. %@NL@%
  21520. %@NL@%
  21521. %@3@%%@CR:C6A-C0077   @%%@AB@%C.14.22  Reading Pointer Values%@AE@%%@EH@%%@NL@%
  21522. %@NL@%
  21523. %@AB@%The input for %p conversion in the fscanf function (4.9.6.2)%@AE@%  %@NL@%
  21524. %@NL@%
  21525. When the %@AB@%%p%@AE@% format character is specified, the %@AB@%fscanf%@AE@% function converts
  21526. pointers from hexadecimal ASCII values into the correct address.  %@NL@%
  21527. %@NL@%
  21528. %@NL@%
  21529. %@3@%%@CR:C6A-C0078   @%%@AB@%C.14.23  Reading Ranges%@AE@%%@EH@%%@NL@%
  21530. %@NL@%
  21531. %@AB@%The interpretation of a dash (-) character that is neither the first nor the
  21532. %@AB@%last character in the scanlist for % [ conversion in the fscanf function
  21533. %@AB@%(4.9.6.2)%@AE@%  %@NL@%
  21534. %@NL@%
  21535. The following line  %@NL@%
  21536. %@NL@%
  21537. %@AS@%  fscanf( fileptr, "%[A-Z]", strptr);%@AE@%%@NL@%
  21538. %@NL@%
  21539. reads any number of characters in the range A-Z into the string to which %@AS@%
  21540. %@AS@%strptr %@AE@% points.  %@NL@%
  21541. %@NL@%
  21542. %@NL@%
  21543. %@3@%%@CR:C6A-C0079   @%%@AB@%C.14.24  File Position Errors%@AE@%%@EH@%%@NL@%
  21544. %@NL@%
  21545. %@AB@%The value to which the macro errno is set by the fgetpos or ftell function
  21546. %@AB@%on failure (4.9.9.1, 4.9.9.4)%@AE@%  %@NL@%
  21547. %@NL@%
  21548. When %@AB@%fgetpos%@AE@% or %@AB@%ftell%@AE@% fails, %@AB@%errno%@AE@% is set to the manifest constant %@AB@%EINVAL%@AE@% if
  21549. the position is invalid or %@AB@%EBADF%@AE@% if the file number is bad. The constants
  21550. are defined in ERRNO.H.  %@NL@%
  21551. %@NL@%
  21552. %@NL@%
  21553. %@3@%%@CR:C6A-C0080   @%%@AB@%C.14.25  Messages Generated by the perror Function%@AE@%%@EH@%%@NL@%
  21554. %@NL@%
  21555. %@AB@%The messages generated by the perror function (4.9.10.4)%@AE@%  %@NL@%
  21556. %@NL@%
  21557. The %@AB@%perror%@AE@% function generates these messages:  %@NL@%
  21558. %@NL@%
  21559. %@AS@%  0  Error 0
  21560. %@AS@%  1 
  21561. %@AS@%  2  No such file or directory
  21562. %@AS@%  3  
  21563. %@AS@%  4 
  21564. %@AS@%  5 
  21565. %@AS@%  6 
  21566. %@AS@%  7  Arg list too long
  21567. %@AS@%  8  Exec format error
  21568. %@AS@%  9  Bad file number
  21569. %@AS@%  10 
  21570. %@AS@%  11 
  21571. %@AS@%  12 Not enough core
  21572. %@AS@%  13 Permission denied
  21573. %@AS@%  14 
  21574. %@AS@%  15 
  21575. %@AS@%  16 
  21576. %@AS@%  17 File exists
  21577. %@AS@%  18 Cross-device link
  21578. %@AS@%  19 
  21579. %@AS@%  20 
  21580. %@AS@%  21 
  21581. %@AS@%  22 Invalid argument
  21582. %@AS@%  23 
  21583. %@AS@%  24 Too many open files
  21584. %@AS@%  25 
  21585. %@AS@%  26 
  21586. %@AS@%  27 
  21587. %@AS@%  28 No space left on device
  21588. %@AS@%  29 
  21589. %@AS@%  30 
  21590. %@AS@%  31 
  21591. %@AS@%  32 
  21592. %@AS@%  33 Math argument
  21593. %@AS@%  34 Result too large
  21594. %@AS@%  35 
  21595. %@AS@%  36 Resource deadlock would occur%@AE@%%@NL@%
  21596. %@NL@%
  21597. %@NL@%
  21598. %@3@%%@CR:C6A-C0081   @%%@AB@%C.14.26  Allocating Zero Memory%@AE@%%@EH@%%@NL@%
  21599. %@NL@%
  21600. %@AB@%The behavior of the calloc, malloc, or realloc function if the size
  21601. %@AB@%requested is zero (4.10.3)%@AE@%  %@NL@%
  21602. %@NL@%
  21603. The %@AB@%calloc%@AE@%, %@AB@%malloc%@AE@%, and %@AB@%realloc %@AE@%functions accept zero as an argument. No
  21604. actual memory is allocated, but the memory size can be modified later by
  21605. %@AB@%realloc%@AE@%.  %@NL@%
  21606. %@NL@%
  21607. %@NL@%
  21608. %@3@%%@CR:C6A-C0082   @%%@AB@%C.14.27  The abort Function%@AE@%%@EH@%%@NL@%
  21609. %@NL@%
  21610. %@AB@%The behavior of the abort function with regard to open and temporary  files
  21611. %@AB@%(4.10.4.1)%@AE@%  %@NL@%
  21612. %@NL@%
  21613. The %@AB@%abort%@AE@% function does not close files that are open or temporary. It does
  21614. not flush stream buffers.  %@NL@%
  21615. %@NL@%
  21616. %@NL@%
  21617. %@3@%%@CR:C6A-C0083   @%%@AB@%C.14.28  The atexit Function%@AE@%%@EH@%%@NL@%
  21618. %@NL@%
  21619. %@AB@%The status returned by the atexit function if the value of the argument is
  21620. %@AB@%other than zero, EXIT_SUCCESS, or EXIT_FAILURE (4.10.4.3r)%@AE@%  %@NL@%
  21621. %@NL@%
  21622. The %@AB@%atexit %@AE@%function returns zero if successful, or a nonzero value if
  21623. unsuccessful.  %@NL@%
  21624. %@NL@%
  21625. %@NL@%
  21626. %@3@%%@CR:C6A-C0084   @%%@AB@%C.14.29  Environment Names%@AE@%%@EH@%%@NL@%
  21627. %@NL@%
  21628. %@AB@%The set of environment names and the method for altering the environment
  21629. %@AB@%list used by the getenv function (4.10.4.4)%@AE@%  %@NL@%
  21630. %@NL@%
  21631. The set of environment names is unlimited.  %@NL@%
  21632. %@NL@%
  21633. To change environment variables from within a C program, call the %@AB@%putenv%@AE@%
  21634. function. To change environment variables from the DOS command line, use the
  21635. SET command (for example, SET LIB = D:\ LIBS).  %@NL@%
  21636. %@NL@%
  21637. Environment variables exist only as long as their host copy of DOS is
  21638. running. For example, the line  %@NL@%
  21639. %@NL@%
  21640. %@AS@%  system( "SET LIB = D:\LIBS" );%@AE@%%@NL@%
  21641. %@NL@%
  21642. would run a copy of DOS, set the environment variable LIB, and return to the
  21643. C program, exiting the secondary copy of DOS. Exiting that copy of DOS
  21644. removes the temporary environment variable LIB.  %@NL@%
  21645. %@NL@%
  21646. Likewise, changes made by the %@AB@%putenv%@AE@% function last only until the program
  21647. ends.  %@NL@%
  21648. %@NL@%
  21649. %@NL@%
  21650. %@3@%%@CR:C6A-C0085   @%%@AB@%C.14.30  The system Function%@AE@%%@EH@%%@NL@%
  21651. %@NL@%
  21652. %@AB@%The contents and mode of execution of the string by the system function
  21653. %@AB@%(4.10.4.5)%@AE@%  %@NL@%
  21654. %@NL@%
  21655. The %@AB@%system%@AE@% function executes an internal DOS or OS/2 command, or an EXE,
  21656. COM, or BAT file from within a C program rather than from the command line.
  21657. %@NL@%
  21658. %@NL@%
  21659. It examines the COMSPEC environment variable to find the command
  21660. interpreter, which is typically COMMAND.COM in DOS or CMD.EXE in OS/2. The
  21661. %@AB@%system%@AE@% function then passes the argument string to the command interpreter.
  21662. %@NL@%
  21663. %@NL@%
  21664. %@NL@%
  21665. %@3@%%@CR:C6A-C0086   @%%@AB@%C.14.31  The strerror Function%@AE@%%@EH@%%@NL@%
  21666. %@NL@%
  21667. %@AB@%The contents of the error message strings returned by the strerror function
  21668. %@AB@%(4.11.6.2)%@AE@%  %@NL@%
  21669. %@NL@%
  21670. The %@AB@%strerror%@AE@% function generates these messages:  %@NL@%
  21671. %@NL@%
  21672. %@AS@%  0   Error 0
  21673. %@AS@%  1  
  21674. %@AS@%  2   No such file or directory
  21675. %@AS@%  3  
  21676. %@AS@%  4  
  21677. %@AS@%  5  
  21678. %@AS@%  6  
  21679. %@AS@%  7   Arg list too long
  21680. %@AS@%  8   Exec format error
  21681. %@AS@%  9   Bad file number
  21682. %@AS@%  10  
  21683. %@AS@%  11  
  21684. %@AS@%  12  Not enough core
  21685. %@AS@%  13  Permission denied
  21686. %@AS@%  14  
  21687. %@AS@%  15  
  21688. %@AS@%  16  
  21689. %@AS@%  17  File exists
  21690. %@AS@%  18  Cross-device link
  21691. %@AS@%  19  
  21692. %@AS@%  20  
  21693. %@AS@%  21  
  21694. %@AS@%  22  Invalid argument
  21695. %@AS@%  23  
  21696. %@AS@%  24  Too many open files
  21697. %@AS@%  25  
  21698. %@AS@%  26  
  21699. %@AS@%  27  
  21700. %@AS@%  28  No space left on device
  21701. %@AS@%  29  
  21702. %@AS@%  30  
  21703. %@AS@%  31  
  21704. %@AS@%  32  
  21705. %@AS@%  33  Math argument
  21706. %@AS@%  34  Result too large
  21707. %@AS@%  35  
  21708. %@AS@%  36  Resource deadlock would occur%@AE@%%@NL@%
  21709. %@NL@%
  21710. %@NL@%
  21711. %@3@%%@CR:C6A-C0087   @%%@AB@%C.14.32  The Time Zone%@AE@%%@EH@%%@NL@%
  21712. %@NL@%
  21713. %@AB@%The local time zone and Daylight Saving Time (4.12.1)%@AE@%  %@NL@%
  21714. %@NL@%
  21715. The local time zone is Pacific Standard Time. Microsoft C supports Daylight
  21716. Saving Time.  %@NL@%
  21717. %@NL@%
  21718. %@NL@%
  21719. %@3@%%@CR:C6A-C0088   @%%@AB@%C.14.33  The clock Function%@AE@%%@EH@%%@NL@%
  21720. %@NL@%
  21721. %@AB@%The era for the clock function (4.12.2.1)%@AE@%  %@NL@%
  21722. %@NL@%
  21723. The %@AB@%clock %@AE@%function's era begins (with a value of 0) when the C program
  21724. starts to execute. It returns times measured in 1/1000th seconds.  %@NL@%
  21725. %@NL@%
  21726. %@NL@%
  21727. %@NL@%
  21728. %@CR:GeneralIndex@%
  21729. %@1@%%@AB@%INDEX%@AE@%%@EH@%%@NL@%
  21730. %@AB@%──────────────────────────────────────────────────────────────────────────
  21731.  
  21732.  
  21733.  
  21734. 80x87 coprocessor%@BO:       309cd@%%@BO:       370f9@%%@BO:       39bde@%
  21735. 80x87
  21736.   Detection of%@BO:       339af@%
  21737.  
  21738. %@2@%%@AB@%    A%@AE@%%@EH@%%@NL@%
  21739. Alternate math package%@BO:       341c5@%%@BO:       3826d@%
  21740.  
  21741. %@2@%%@AB@%    B%@AE@%%@EH@%%@NL@%
  21742. _based keyword%@BO:       1fe23@%%@BO:       2117b@%%@BO:       21caa@%
  21743.  
  21744. %@2@%%@AB@%    C%@AE@%%@EH@%%@NL@%
  21745. C extensions, PWB
  21746.   building protected-mode%@BO:       66d22@%
  21747.   building real-mode%@BO:       65d11@%%@BO:       66532@%
  21748.   calling C library functions%@BO:       6c61c@%
  21749.   calling C library routines%@BO:       6cb47@%
  21750.   calling PWB functions%@BO:       6a499@%%@BO:       6a9d3@%%@BO:       6b0c7@%%@BO:       6bab9@%%@BO:       6c441@%
  21751.   describing functions and switches%@BO:       67324@%%@BO:       67619@%%@BO:       67de2@%%@BO:       6866c@%
  21752.   initializing functions%@BO:       68b44@%
  21753.   prototyping functions%@BO:       69257@%
  21754.   receiving parameters%@BO:       69257@%%@BO:       699b4@%%@BO:       6a499@%
  21755.   sample%@BO:       650a9@%%@BO:       65b31@%
  21756.   versus executable files%@BO:       64e30@%
  21757. C extentions, PWB
  21758.   building protected-mode%@BO:       66876@%
  21759. Calls
  21760.   Emulator math package%@BO:       3737c@%
  21761.   Emulator package%@BO:       39396@%%@BO:       39bde@%
  21762.   Floating-point%@BO:       3494a@%%@BO:       38cfd@%
  21763.   Math coprocessor package%@BO:       37927@%
  21764. CODEVIEW.LST file%@BO:       77d77@%
  21765. CodeView
  21766.   debugging
  21767.     DLLs with%@BO:       e3f22@%
  21768. CONFIG.SYS file%@BO:       7890b@%
  21769. CONFIG.SYS files%@BO:       d390b@%
  21770. _control87%@BO:       33ec0@%
  21771. Coordinates
  21772.   overview%@BO:       806a5@%
  21773.   physical%@BO:       80b01@%%@BO:       80f5d@%%@BO:       8141f@%
  21774.   screen location%@BO:       81fcd@%
  21775.   viewport%@BO:       8141f@%%@BO:       83d1f@%
  21776.   window%@BO:       81a8a@%%@BO:       81fcd@%%@BO:       82fc7@%%@BO:       83d1f@%%@BO:       845b2@%%@BO:       84b29@%%@BO:       85aa5@%%@BO:       86287@%%@BO:       86c8b@%
  21777. Coprocessor%@BO:       309cd@%
  21778. CURRENT.STS%@BO:       6e5cb@%
  21779.  
  21780. %@2@%%@AB@%    D%@AE@%%@EH@%%@NL@%
  21781. Default math package%@BO:       339af@%
  21782. Denormalized numbers%@BO:       31b6f@%%@BO:       33ec0@%%@BO:       34416@%
  21783. Dot commands%@BO:       59bb9@%%@BO:       59efd@%%@BO:       5ac14@%%@BO:       5ba95@%
  21784. double%@BO:       30ed4@%%@BO:       32a89@%
  21785.  
  21786. %@2@%%@AB@%    E%@AE@%%@EH@%%@NL@%
  21787. 80x87 coprocessor%@BO:       309cd@%%@BO:       370f9@%%@BO:       39bde@%
  21788. 80x87
  21789.   Detection of%@BO:       339af@%
  21790. EMOEM.ASM%@BO:       3a8c0@%
  21791. Emulator math package%@BO:       33170@%%@BO:       3376a@%
  21792. Emulator package
  21793.   In-line%@BO:       366b7@%%@BO:       39bde@%
  21794.   With dynamic-link libraries%@BO:       36ed5@%
  21795. Environment
  21796.   NO87 variable%@BO:       309cd@%%@BO:       39a6a@%
  21797.  
  21798. %@2@%%@AB@%    F%@AE@%%@EH@%%@NL@%
  21799. _far keyword%@BO:       1fe23@%%@BO:       2117b@%%@BO:       21caa@%%@BO:       9f33e@%%@BO:       a0b7f@%%@BO:       b7e65@%
  21800. _fastcall keyword%@BO:       9d859@%
  21801. Files
  21802.   .FON%@BO:       87899@%%@BO:       87d60@%%@BO:       8a479@%
  21803.   CODEVIEW.LST%@BO:       77d77@%
  21804.   CONFIG.SYS%@BO:       7890b@%%@BO:       d390b@%
  21805.   CURRENT.STS%@BO:       6e5cb@%
  21806.   TOOLS.INI See TOOLS.INI%@BO:       460ef@%
  21807. Fill patterns%@BO:       91bc1@%%@BO:       922bf@%%@BO:       92bf4@%
  21808. float%@BO:       30ed4@%%@BO:       32a89@%
  21809. Floating-point accumulator%@BO:       32a89@%
  21810. Floating-point math
  21811.   requirements, DLLs%@BO:       d8678@%
  21812. Floating-point
  21813.   Alternate math package%@BO:       341c5@%%@BO:       3826d@%
  21814.   Biased exponent%@BO:       316fc@%
  21815.   Compatibility between options%@BO:       3913f@%
  21816. Floating-Point
  21817.   Controlling%@BO:       308f3@%
  21818. Floating-point
  21819.   Default math package%@BO:       36898@%
  21820.   Default package%@BO:       339af@%
  21821.   Denormalized numbers%@BO:       31b6f@%%@BO:       33ec0@%%@BO:       34416@%
  21822.   Effect of calls on code size%@BO:       37cb2@%%@BO:       38491@%
  21823.   Effect of calls on speed%@BO:       37d4f@%%@BO:       38491@%%@BO:       38feb@%
  21824.   Effect on optimization%@BO:       36063@%
  21825.   Emulator package%@BO:       33170@%%@BO:       3376a@%
  21826.   Exception masking%@BO:       33ec0@%
  21827.   Exceptions%@BO:       33d51@%%@BO:       3a5d8@%
  21828.   exponent%@BO:       3123f@%
  21829.   Fastest programs%@BO:       372f4@%
  21830.   In libraries%@BO:       3768f@%
  21831.   Infinities%@BO:       34416@%
  21832.   Interrupt-enable%@BO:       33ec0@%
  21833.   Library considerations for%@BO:       386a4@%
  21834.   Mantissa%@BO:       3123f@%
  21835.   Math coprocessor package%@BO:       33212@%%@BO:       33f87@%
  21836.   Maximizing accuracy%@BO:       33a98@%
  21837.   NaNs%@BO:       34416@%
  21838.   On non-IBM compatible computers%@BO:       3a2a8@%
  21839.   Packages%@BO:       33116@%%@BO:       3353d@%
  21840.   Precision%@BO:       3210e@%
  21841.   Program size%@BO:       34143@%%@BO:       341c5@%
  21842.   Program speed%@BO:       34143@%%@BO:       341c5@%
  21843.   Sign bit%@BO:       31380@%
  21844.   Smallest programs%@BO:       372f4@%
  21845.   Transcendental function results%@BO:       33cce@%
  21846.   Underflow%@BO:       33ec0@%
  21847.   Using in dynamic-link libraries%@BO:       345ba@%
  21848.   With libraries not provided by Microsoft%@BO:       37728@%
  21849. .FON files%@BO:       87899@%%@BO:       87d60@%%@BO:       8a479@%
  21850. /FPa%@BO:       3826d@%
  21851. /FPc%@BO:       3737c@%%@BO:       39396@%%@BO:       39bde@%
  21852. /FPc87%@BO:       37927@%
  21853. /FPi%@BO:       366b7@%%@BO:       39bde@%
  21854. /FPi87%@BO:       36f6a@%
  21855. Function calls
  21856.    near call%@BO:       16856@%
  21857.   C calling convention%@BO:       19198@%
  21858.   FORTRAN/Pascal calling convention%@BO:       19198@%%@BO:       19c0f@%
  21859.   register calling convention%@BO:       19c0f@%
  21860.   _fastcall calling convention%@BO:       19c0f@%%@BO:       1a9ca@%%@BO:       1b06e@%%@BO:       1b6f2@%
  21861. Functions
  21862.   drive and directory (list)%@BO:       eafe2@%
  21863.   graphics (list)%@BO:       82c5e@%
  21864.   initializing%@BO:       68b44@%
  21865.   prototyping%@BO:       69257@%
  21866.   Returning floating-point types%@BO:       32643@%
  21867.   WhenLoaded%@BO:       68b44@%
  21868.  
  21869. %@2@%%@AB@%    G%@AE@%%@EH@%%@NL@%
  21870. /Gd option%@BO:       eb7e9@%
  21871. Gd option%@BO:       19198@%
  21872. Graphics
  21873.   video modes 
  21874.      default mode%@BO:       7b01e@%
  21875.      graphics mode, defined%@BO:       7b01e@%
  21876.      text mode, defined%@BO:       7b01e@%
  21877.  
  21878. %@2@%%@AB@%    H%@AE@%%@EH@%%@NL@%
  21879. Help files
  21880.   local help context%@BO:       568ec@%
  21881. HIMEM.SYS driver%@BO:       7890b@%
  21882. _huge keyword%@BO:       e7371@%
  21883. _huge Keyword%@BO:       1dce4@%
  21884. _huge keyword%@BO:       1fe23@%%@BO:       2117b@%%@BO:       21caa@%%@BO:       b7caa@%%@BO:       b7e65@%
  21885.  
  21886. %@2@%%@AB@%    I%@AE@%%@EH@%%@NL@%
  21887. IEEE%@BO:       30b59@%%@BO:       34416@%%@BO:       36063@%
  21888. In-line assembly
  21889.   advantages%@BO:       28854@%
  21890. In-line
  21891.   Floating-point emulator package%@BO:       366b7@%
  21892.   Floating-point emulator%@BO:       39bde@%
  21893.   Floating-point instructions%@BO:       38cfd@%
  21894.   Floating-point math coprocessor package%@BO:       36f6a@%
  21895.   Floating-point%@BO:       3494a@%
  21896. Institute of Electrical and Electronics Engineers
  21897.    %@AI@%see%@AE@% IEEE%@NL@%; %@AI@%see%@AE@% %@NL@%
  21898.  
  21899. %@2@%%@AB@%    L%@AE@%%@EH@%%@NL@%
  21900. Language conventions
  21901.   calling conventions%@BO:       9d0ff@%%@BO:       9d859@%
  21902.   naming conventions%@BO:       9bde5@%%@BO:       9c6f1@%%@BO:       9cf4d@%
  21903.   parameter-passing conventions%@BO:       9e336@%%@BO:       9f33e@%
  21904. Libraries
  21905.   dynamic-link See DLLs%@BO:       c58c8@%
  21906.   import%@BO:       c7173@%%@BO:       c77ce@%
  21907.   special%@BO:       c2ecf@%%@BO:       c39de@%
  21908. LINK
  21909.   /EXEPACK option%@BO:       184e3@%
  21910.   /FARCALLTRANSLATION option%@BO:       16856@%
  21911.   /NODEFAULTLIBRARYSEARCH (/NOD) option%@BO:       c1915@%%@BO:       c247b@%%@BO:       c77ce@%
  21912.   /NOEXTENDEDDICTSEARCH (/NOE) option%@BO:       c7d3e@%
  21913.   /NOIGNORECASE (/NOI) option%@BO:       c7d3e@%
  21914.   /PACKCODE option%@BO:       17100@%
  21915.   /PACKDATA option%@BO:       1812a@%%@BO:       18322@%
  21916.   /PADCODE option%@BO:       3c4e6@%
  21917.   /PADDATA option%@BO:       3c4e6@%%@BO:       3c641@%
  21918.   /TINY option%@BO:       1df3d@%
  21919.   compatibility (/Lc)%@BO:       c1915@%
  21920.   PACKCODE option%@BO:       17bab@%
  21921.   protected-mode (/Lp)%@BO:       c1915@%%@BO:       c247b@%
  21922.   real-mode (/Lr)%@BO:       c1915@%%@BO:       c247b@%
  21923. LLIBCDLL.LIB%@BO:       345ba@%
  21924. long double%@BO:       30ed4@%%@BO:       32a89@%%@BO:       32d2a@%
  21925.  
  21926. %@2@%%@AB@%    M%@AE@%%@EH@%%@NL@%
  21927. Macros
  21928.   inherited%@BO:       454a5@%
  21929. Math coprocessor package%@BO:       33212@%%@BO:       33f87@%
  21930.   In-line%@BO:       36f6a@%
  21931.  
  21932. %@2@%%@AB@%    N%@AE@%%@EH@%%@NL@%
  21933. _near keyword%@BO:       1fe23@%%@BO:       2117b@%%@BO:       21caa@%%@BO:       9f33e@%%@BO:       a0b7f@%%@BO:       b7e65@%
  21934. NO87%@BO:       309cd@%%@BO:       39a6a@%
  21935.  
  21936. %@2@%%@AB@%    O%@AE@%%@EH@%%@NL@%
  21937. optimise pragma%@BO:       14ce4@%%@BO:       1546c@%
  21938. Optimization
  21939.   Effect of floating-point math on%@BO:       36063@%%@BO:       381c4@%
  21940. optimize pragma%@BO:       11ff2@%%@BO:       14815@%
  21941. OS/2 
  21942.   calling%@BO:       bede0@%
  21943.  
  21944. %@2@%%@AB@%    P%@AE@%%@EH@%%@NL@%
  21945. Process
  21946.   child%@BO:       e4420@%
  21947.   debugging multiple processes%@BO:       d390b@%
  21948. Programmer's WorkBench
  21949.    %@AI@%see%@AE@% PWB%@NL@%; %@AI@%see%@AE@% %@NL@%
  21950. Pseudotargets%@BO:       48ea4@%%@BO:       4922a@%
  21951. PWB
  21952.   80x87 option%@BO:       363c0@%
  21953.   Debug Build Options%@BO:       36200@%
  21954.   Emulation calls option%@BO:       36305@%
  21955.   extensions.See C extensions, PWB%@BO:       650a9@%
  21956.   Fast alternate math option%@BO:       3646a@%
  21957.   Global Compile Options%@BO:       36200@%
  21958.   Inline 80x87 Instructions option%@BO:       36658@%
  21959.   Inline Emulation option%@BO:       36526@%
  21960.   Release Build Options%@BO:       36200@%
  21961.   Selecting floating-point options from%@BO:       3494a@%
  21962.  
  21963. %@2@%%@AB@%    R%@AE@%%@EH@%%@NL@%
  21964. Run-time
  21965.   support of type long double%@BO:       32d2a@%
  21966.  
  21967. %@2@%%@AB@%    S%@AE@%%@EH@%%@NL@%
  21968. SETUP%@BO:       333b8@%
  21969. SLLs
  21970.   data segments%@BO:       253a7@%
  21971.  
  21972. %@2@%%@AB@%    T%@AE@%%@EH@%%@NL@%
  21973. Threads
  21974.   _beginthread function%@BO:       cc91d@%
  21975.   _endthread function%@BO:       cc91d@%
  21976. /TINY option%@BO:       1df3d@%
  21977. Type
  21978.   double%@BO:       30ed4@%
  21979.   float%@BO:       30ed4@%
  21980.   long double%@BO:       30ed4@%
  21981.   Promotion of floating point%@BO:       3234a@%
  21982.   Range of floating-point%@BO:       31d97@%
  21983.   Significance of floating-point%@BO:       30ed4@%
  21984.   Storage requirements for floating-point%@BO:       30ed4@%
  21985.   Widening for floating-point types%@BO:       32170@%
  21986. Types
  21987.   double%@BO:       32a89@%
  21988.   float%@BO:       32a89@%
  21989.   long double%@BO:       32a89@%%@BO:       32d2a@%
  21990.  
  21991. %@2@%%@AB@%    V%@AE@%%@EH@%%@NL@%
  21992. Variables
  21993.   Declaring as floating-point types%@BO:       30d03@%
  21994.   Precision with floating-point%@BO:       3210e@%
  21995.   Promotion of floating-point%@BO:       3234a@%
  21996.   Range of floating-point%@BO:       31d97@%
  21997.   Significance of%@BO:       30ed4@%
  21998.   Storage requirements for%@BO:       30ed4@%
  21999.  
  22000.