1470 lines
52 KiB
Plaintext
1470 lines
52 KiB
Plaintext
|
|
README.DOC File
|
|
|
|
Release Notes for the Microsoft(R) C Optimizing Compiler
|
|
Version 5.10
|
|
|
|
(C) Copyright Microsoft Corporation, 1987, 1988
|
|
|
|
|
|
This document contains release notes for Version 5.10 of the Microsoft(R) C
|
|
Optimizing Compiler and libraries for MS-DOS(R). The information in this
|
|
document is more up to date than that in the manuals.
|
|
|
|
Microsoft improves its languages documentation at the time of reprinting, so
|
|
some of the information in this on-line file may already be included in your
|
|
manuals.
|
|
|
|
|
|
===================< Requesting Assistance from Microsoft >====================
|
|
|
|
If you need to contact Microsoft Product Support for assistance, the four-digit
|
|
phone code for the Microsoft C Optimizing Compiler is 1222.
|
|
|
|
|
|
======================< Other On-Line Documents >==============================
|
|
|
|
For additional information, consult the files listed below. Note that the
|
|
SETUP program gives you the option of copying all documentation files to your
|
|
hard disk.
|
|
|
|
File Disk Information:
|
|
---- ---- ------------
|
|
|
|
ERRMSG.DOC 1 New and changed error messages for all
|
|
software in this release
|
|
|
|
SETUP.DOC 1 Using the SETUP program to install
|
|
this product
|
|
|
|
FPEXCEPT.DOC 1 Handling floating-point exceptions
|
|
|
|
UTILITY.DOC 3 Microsoft CodeView(R) debugger and
|
|
utilities
|
|
|
|
README.QC 3 Microsoft QuickC(TM) Compiler
|
|
|
|
\STARTUP\README.DOC 3 Start-up source files
|
|
|
|
\PATCH\PATCH87.DOC 3 Patch for MS-DOS 3.20
|
|
|
|
\PATCH\PATCH320.DOC 3 Patch for IBM(R) PC-DOS 3.20
|
|
|
|
\SOURCE\SAMPLES.DOC 14 Demo programs included in this release
|
|
|
|
\SOURCE\CFLOW.DOC 14 CFLOW.C demonstration program
|
|
|
|
|
|
|
|
|
|
|
|
=============================< Contents >======================================
|
|
|
|
This file has four parts. Each part contains the notes for one of the manuals
|
|
included in this release. Within each part, every note indicates the manual
|
|
page to which it refers.
|
|
|
|
Part Notes for:
|
|
---- ----------
|
|
|
|
1 Microsoft C Optimizing Compiler 5.1 Update
|
|
|
|
2 Microsoft C Optimizing Compiler User's Guide
|
|
|
|
3 Microsoft C Optimizing Compiler Run-Time Library Reference
|
|
|
|
4 Microsoft C Optimizing Language Reference
|
|
|
|
|
|
|
|
====< Part 1: Notes for the Microsoft C Optimizing Compiler 5.1 Update >=======
|
|
|
|
The following notes refer to specific pages in the Microsoft C Optimizing
|
|
Compiler 5.1 Update.
|
|
|
|
Page Note
|
|
---- ----
|
|
12 The comment Pragma
|
|
------------------
|
|
This release does not support the exestr record type of the comment
|
|
pragma.
|
|
|
|
|
|
13 The data_seg Pragma
|
|
-------------------
|
|
The data_seg pragma names the data segment to be used by subsequent
|
|
load-DS functions and subsequent allocations of static and global data
|
|
items. However, it does not, in itself, cause a function to load a data
|
|
segment. Use the /Au option or the _loadds keyword to cause a function
|
|
to load a data segment upon entry.
|
|
|
|
|
|
21 The _saveregs Keyword
|
|
---------------------
|
|
The _saveregs keyword is useful in any case where it is not certain
|
|
what the register conventions of the caller might be. For instance,
|
|
_saveregs could be used for a general-purpose function that will reside
|
|
in a dynamic-link library. Since a function in a dynamic-link library
|
|
might be called from any language, you may choose not to assume
|
|
Microsoft C calling conventions in some cases.
|
|
|
|
|
|
|
|
====< Part 2: Notes for the Microsoft C Optimizing Compiler User's Guide >=====
|
|
|
|
The following notes refer to specific pages in the Microsoft C Optimizing
|
|
Compiler User's Guide.
|
|
|
|
Page Note
|
|
---- ----
|
|
|
|
29 C1L.EXE
|
|
-------
|
|
This release includes an alternate form of compiler pass 1 named
|
|
C1L.EXE. This compiler pass can be used to compile programs that get
|
|
the error message "out of near heap space." Invoke C1L.EXE by entering
|
|
the CL command with the /B1 <path> option
|
|
|
|
cl /B1 <path>\c1l.exe <sourcefile>.c
|
|
|
|
In the preceding command, <path> is the path (including drive and
|
|
directory) where C1L.EXE resides, and <sourcefile> is the name of the
|
|
C source file you wish to compile.
|
|
|
|
|
|
32 Assembling Start-Up Source Files
|
|
--------------------------------
|
|
The start-up source files provided with Version 5.10 should be
|
|
assembled with Version 5.00A or higher of the Microsoft Macro
|
|
Assembler (MASM).
|
|
|
|
|
|
47 MSC Driver
|
|
----------
|
|
The MSC compiler driver is not supported in Version 5.10. If you have
|
|
batch files that use the MSC command, you can make the following
|
|
global changes to MSC command lines to ensure that your programs
|
|
compile in the same way:
|
|
|
|
1. Replace any MSC command with a CL command.
|
|
|
|
2. Replace the terminating semicolon on the MSC command line
|
|
with the /c (compile only) CL option.
|
|
|
|
3. If commas appear on the MSC command line:
|
|
|
|
Replace the first comma (preceding the object-file name)
|
|
with /Fo. (This step is not required if no file name follows
|
|
the first comma, that is, if the comma is used only as a
|
|
placeholder.)
|
|
|
|
Replace the second comma (preceding the source-listing-file
|
|
name) with the /Fs option.
|
|
|
|
Replace the third comma (preceding the object-listing-file
|
|
name) with the /Fc option.
|
|
|
|
Note that each of these options must appear immediately before
|
|
the corresponding file name, with no intervening spaces.
|
|
|
|
For example, to convert the MSC command line
|
|
|
|
MSC test.c,,,;
|
|
|
|
to a CL command line, follow these steps:
|
|
|
|
1. Replace the MSC command with a CL command, as follows:
|
|
|
|
CL test.c,,,;
|
|
|
|
2. Replace the semicolon with the /c option, as follows:
|
|
|
|
CL test.c,,src.lst, /c
|
|
|
|
3. Since no object-file name follows the first comma, you do
|
|
not need to add an /Fo option. Replace the first comma with
|
|
a blank and the second comma with an /Fs option, as follows:
|
|
|
|
CL test.c /Fssrc.lst, /c
|
|
|
|
4. Replace the second comma with an /Fc option, as follows:
|
|
|
|
CL test.c /Fssrc.lst /Fc /c
|
|
|
|
|
|
48 Specifying Overlays
|
|
-------------------
|
|
You can specify overlays on the CL command line. Simply enclose the
|
|
names of the overlay source or object files in parentheses. For
|
|
example, if you enter the command line
|
|
|
|
cl src_1.c (src_2.c obj_1) obj_2
|
|
|
|
the modules SRC_2.OBJ and OBJ_1.OBJ are put in an overlay in the
|
|
SRC_1.EXE file. They are read into memory from disk only if and when
|
|
they are needed. The QCL command supports the same syntax for
|
|
specifying overlays.
|
|
|
|
|
|
53 /Zc Option
|
|
----------
|
|
The new /Zc option causes any name declared with the pascal keyword
|
|
to be case-insensitive.
|
|
|
|
|
|
61 /Fa Option
|
|
----------
|
|
You must use Version 5.10 of the Microsoft Macro Assembler to assemble
|
|
output from the /Fa option. Earlier versions of the Macro Assembler do
|
|
not support the new communal variables generated by the /Fa option.
|
|
|
|
|
|
75 /D Option
|
|
---------
|
|
Note that the /Didentifier= and /Didentifier=string forms of this
|
|
option cannot be defined in the CL environment variable. This is
|
|
because the SET command does not accept the equal sign (=), which is
|
|
a special character in the environment.
|
|
|
|
|
|
77 Predefined Identifiers
|
|
----------------------
|
|
The compiler defines the following new identifiers:
|
|
|
|
Identifier Function
|
|
---------- --------
|
|
M_I8086 The M_I8086 identifier identifies the target
|
|
processor as an 8086. It is defined by default or
|
|
when the /G0 option is used.
|
|
|
|
M_I286 The M_I286 identifier identifies the target
|
|
processor as an 80286. It is defined when the
|
|
/G1 or /G2 option is given.
|
|
|
|
You can still give the same number of /D options on the CL command
|
|
line.
|
|
|
|
Note that the /U option no longer removes the definition of the
|
|
predefined identifier M_I86mM, which identifies the memory model. You
|
|
can use the /U option to remove the definition of M_I86mM. However,
|
|
if you do, the NULL constant will not be defined automatically in the
|
|
program (since the definition of NULL in the stdio.h and stddef.h
|
|
files depends on the memory model in use). If you compile a program
|
|
with the /UM_I86mM option, be sure to define NULL explicitly if you
|
|
use it in the program.
|
|
|
|
|
|
89 /Ow Option
|
|
----------
|
|
The new /Ow option is useful in developing Windows applications. It
|
|
has the same effect as the /Oa optimization option, except that the
|
|
compiler assumes that ANY function call can potentially alter the value
|
|
of any variable, including local variables. For example, the following
|
|
program prints the word "pass" when compiled with the /Ow option, and
|
|
prints the word "fail" when compiled with the /Oa option:
|
|
|
|
main()
|
|
{
|
|
int *p, i;
|
|
i = 5;
|
|
sample((int)&i);
|
|
if (i != 5) puts("pass");
|
|
else puts("fail");
|
|
}
|
|
|
|
#ifdef EXEC
|
|
sample( a )
|
|
int a;
|
|
{
|
|
*(int *)a = 2;
|
|
}
|
|
#endif
|
|
|
|
The /Oa option, which /Ow resembles, tells the compiler that no
|
|
aliasing is being done. That is, when you tell the compiler that you
|
|
are passing a locally declared int value, as in the previous example,
|
|
that int value cannot be changed by a function call. The previous
|
|
example, which is common in Windows development, uses a cast on the
|
|
argument to fool the compiler. The function call says that it is
|
|
passing an int value, but it actually passes a pointer that is later
|
|
used by the function to modify data.
|
|
|
|
Windows does not discriminate between far pointers and unsigned long
|
|
types (the type used for all arguments in Windows). Furthermore, in
|
|
a Windows application, it is possible that data segments can move in
|
|
memory at the time of a function call, allowing the address of a data
|
|
item to change across the function call. The /Oa option assumes that
|
|
this is not the case. The /Ow option is a compromise that tells the
|
|
compiler that no aliasing is being done, EXCEPT across function calls.
|
|
This preserves the compiler's ability to do good local optimization,
|
|
but prevents it from keeping common subexpressions alive across
|
|
function calls.
|
|
|
|
|
|
93 /On Option
|
|
----------
|
|
The new /On option disables potentially unsafe loop optimizations in
|
|
programs compiled with the /Ol or /Ox option. When the /On option
|
|
is used, the compiler does not perform the following type of loop
|
|
optimization:
|
|
|
|
Hoisting Division Operations Out of Loops
|
|
-----------------------------------------
|
|
This type of optimization can cause problems in code such as the
|
|
following:
|
|
|
|
for (i=0; i<=99; i+=10)
|
|
{
|
|
if (denom != 0)
|
|
{
|
|
array[i] += (numer/denom);
|
|
printf("%f ", array[i]);
|
|
}
|
|
}
|
|
|
|
When loop optimizations are turned on, the compiler knows that
|
|
numer/denom does not change within the loop. Therefore, it
|
|
calculates numer/denom only once: before the start of the loop
|
|
and before the if statement within the loop can check for
|
|
division by zero. Compiling with the /On option helps to avoid
|
|
error message C2023, "divide by zero," which may result from code
|
|
like that shown above.
|
|
|
|
In general, you may want to compile with /On if your programs use
|
|
arrays that are larger than 32K, or if you experience division-by-
|
|
zero or infinite-loop errors in programs compiled with the /Ol option.
|
|
|
|
|
|
93 Generating Intrinsic Functions (/Oi Option, intrinsic Pragma)
|
|
-------------------------------------------------------------
|
|
In addition to the functions listed in the manual, the following
|
|
functions have intrinsic forms:
|
|
|
|
Floating-point Functions
|
|
------------------------
|
|
acos, asin, atan, atan2, cos, cosh, exp, fabs, fmod, log, log10,
|
|
pow, sin, sinh, sqrt, tan, tanh
|
|
|
|
Other Functions
|
|
---------------
|
|
_enable, _disable, inpw, outpw
|
|
|
|
If you use intrinsic forms of the floating-point functions listed
|
|
above (that is, if you compile with the /Oi option or specify any of
|
|
the functions in an intrinsic pragma), you cannot link with an
|
|
alternate math library (mLIBCA.LIB). Any attempt to do so will cause
|
|
linker errors arising from unresolved external references. Note that
|
|
this restriction applies even if you link with an alternate math
|
|
library after compiling with the /FPc or /FPc87 option.
|
|
|
|
If you want to compile with /Oi (to use the intrinsic forms of
|
|
non-floating-point functions) and then link with an alternate-math
|
|
library, specify any floating-point functions that appear in a
|
|
program in a function pragma.
|
|
|
|
|
|
96 /Ox Option
|
|
----------
|
|
For Version 5.10, the /Ox (maximum optimization) option performs more
|
|
optimizations than in previous versions, including loop optimizations
|
|
and generation of intrinsic forms for certain library functions. If
|
|
you have problems compiling programs with the /Ox option, try breaking
|
|
the option down to its component parts and removing either the
|
|
"i" (generate intrinsic forms) or the "l" (perform loop optimizations)
|
|
from the option string, and recompiling. For Version 5.10, the
|
|
"expanded" version of the /Ox option is
|
|
|
|
/Oailt /Gs
|
|
|
|
|
|
99 /Za and /Ze Options
|
|
-------------------
|
|
Three new Microsoft extensions have been added to the list in
|
|
Section 3.3.14:
|
|
|
|
1. Casting data pointers to function pointers, as in the following
|
|
example:
|
|
|
|
int *ip;
|
|
int sample();
|
|
|
|
((int (*)())ip)();
|
|
|
|
2. Casting function pointers to data pointers, as in the following
|
|
example:
|
|
|
|
int *ip;
|
|
int sample();
|
|
|
|
ip = (int *)sample;
|
|
|
|
Casts like these generate error C2068, "illegal cast," in programs
|
|
compiled with the /Za option. Otherwise, they generate warning
|
|
C4074, "non standard extension used," at warning level 3 or higher.
|
|
|
|
The ANSI-standard way to cast from data pointers to function
|
|
pointers, and from function pointers to data pointers, is to
|
|
|
|
- Cast to an integral type (int or long depending on
|
|
pointer size)
|
|
|
|
- Cast to the final pointer type
|
|
|
|
For example, in a small-model program, the previous examples could
|
|
be rewritten as follows to conform to the ANSI convention:
|
|
|
|
/* cast function pointer to data pointer */
|
|
ip = (int *)(int)sample;
|
|
|
|
/* cast data pointer to function pointer */
|
|
((int (*)())(int)ip)();
|
|
|
|
Examples like those above work correctly whether or not the program
|
|
is compiled with the /Za option. Note that the compiler generates
|
|
identical code in both cases; the only difference is that one form
|
|
is ANSI-compatible, and the other is not.
|
|
|
|
3. Using an ellipsis in a function prototype and a fixed parameter
|
|
list in the definition of that function, as shown in the
|
|
following code fragment:
|
|
|
|
int sample(int,...);
|
|
int sample(int a, int b)
|
|
{
|
|
}
|
|
|
|
The preceding code generates warning C4028, "parameter
|
|
declaration different" when compiled with /Za (language
|
|
extensions disabled) and warning C4074, "non standard
|
|
extension used - function declaration used ellipsis," when
|
|
compiled with language extensions (enabled by default, or
|
|
with the /Ze option).
|
|
|
|
|
|
99 The interrupt Attribute
|
|
------------------------
|
|
The interrupt attribute can be applied to a function to tell the
|
|
compiler that the function is an interrupt handler. This attribute
|
|
tells the compiler to generate entry and exit sequences that are
|
|
appropriate for an interrupt-handling function, including saving and
|
|
restoring registers and executing an IRET instruction to return.
|
|
|
|
When an interrupt function is called, the DS register is initialized
|
|
to the C data segment. This allows you to access global variables from
|
|
within an interrupt function.
|
|
|
|
In addition, all registers (except SS) are saved on the stack. You
|
|
can access these registers within the function if you declare a
|
|
function parameter list containing a formal parameter for each
|
|
saved register. The following example illustrates such a declaration:
|
|
|
|
void interrupt cdecl far int_handler (unsigned es, unsigned ds,
|
|
unsigned di, unsigned si, unsigned bp, unsigned sp,
|
|
unsigned bx, unsigned dx, unsigned cx, unsigned ax,
|
|
unsigned ip, unsigned cs, unsigned flags)
|
|
{
|
|
}
|
|
|
|
The order in which the formal parameters must appear is the opposite
|
|
order from which they are pushed onto the stack. You can omit
|
|
parameters from the end of the list in a declaration, but not from
|
|
the beginning. For example, if your handler needs to use only DI and
|
|
SI, you must still provide ES and DS, but not necessarily BX or DX.
|
|
|
|
The compiler always saves and restores registers in the same, fixed
|
|
order. Thus, no matter what names you use in the formal parameter
|
|
list, the first parameter in the list refers to ES, the second refers
|
|
to DS, and so on.
|
|
|
|
You can pass additional arguments if your interrupt handler will be
|
|
called directly from C rather than by an INT instruction. To do this,
|
|
you must declare all register parameters and then declare your
|
|
parameter at the end of the list.
|
|
|
|
If you change any of the parameters of an interrupt function while
|
|
the function is executing, the corresponding register contains the
|
|
changed value when the function returns. For example:
|
|
|
|
void interrupt cdecl far int_handler (unsigned es, unsigned ds,
|
|
unsigned di, unsigned si)
|
|
{
|
|
di = -1;
|
|
}
|
|
|
|
This causes the DI register to contain -1 when the int_handler
|
|
function returns. In general, it is not a good idea to modify the
|
|
values of the parameters representing the IP and CS registers in
|
|
interrupt functions. If you need to modify a particular flag,
|
|
such as the carry flag for certain DOS and BIOS interrupt
|
|
routines, use the OR operator (|) so that other bits in the flags
|
|
register are not changed.
|
|
|
|
When an interrupt function is called by an INT instruction, the
|
|
interrupt enable flag is cleared. If your function needs to do
|
|
significant processing, you should use the _enable function to set
|
|
the interrupt flag so that interrupts can be handled.
|
|
|
|
Interrupt functions often need to transfer control to a second
|
|
interrupt routine. This can be done in two ways:
|
|
|
|
1. You can call the interrupt routine (after casting it to an
|
|
interrupt function if necessary). Do this if you need to do
|
|
further processing after the second interrupt routine finishes.
|
|
|
|
void interrupt cdecl new_int ()
|
|
{
|
|
... /* Initial processing here */
|
|
(*old_int) ();
|
|
... /* Final processing here */
|
|
}
|
|
|
|
2. Call _chain_intr with the interrupt routine as an argument.
|
|
Do this if your routine is finished and you want the second
|
|
interrupt routine to terminate the interrupt call.
|
|
|
|
void interrupt cdecl new_int ()
|
|
{
|
|
... /* Initial processing here */
|
|
_chain_intr (old_int);
|
|
/* This is never executed */
|
|
}
|
|
|
|
In general, it is not a good idea for an interrupt function to call
|
|
standard-library functions, especially functions that rely on DOS
|
|
INT 21H or BIOS calls. Functions that rely on INT 21H calls include
|
|
I/O functions and _dos functions. Functions that rely on the BIOS
|
|
include graphics functions and _bios functions. It may be safe to use
|
|
functions that do not rely on INT 21H or BIOS, such as string-handling
|
|
functions. Before using a standard-library function in an interrupt
|
|
function, be sure that you are familiar with the library function and
|
|
what it does.
|
|
|
|
|
|
100 /Zp Option
|
|
----------
|
|
In Version 5.0 and higher, a structure or union whose members have only
|
|
the types char or unsigned char, or any array of those types, is
|
|
byte-aligned. That is, every such structure or union is sized exactly,
|
|
not padded to an even number of bytes as in Version 4.0. If a structure
|
|
or union contains any member whose type is not char or unsigned char,
|
|
there is no difference between Versions 4.0 and 5.0. (Note that this
|
|
change makes a difference only if the sum of the sizes of the members
|
|
is odd; if the sum is even, then no alignment byte is added.)
|
|
|
|
This example demonstrates the difference between Versions 4.0 and 5.x:
|
|
|
|
char a;
|
|
struct {char a, b, c} y;
|
|
struct {char a[3]} z;
|
|
main()
|
|
{
|
|
printf( "Size of y = %d\n", sizeof(y) );
|
|
printf( "Size of z = %d\n", sizeof(z) );
|
|
}
|
|
|
|
If the preceding code is compiled with Version 4.0 (not using /Zp),
|
|
the output is :
|
|
|
|
Size of y = 4
|
|
Size of z = 4
|
|
|
|
If the above sample is compiled with Version 5.0 and higher (not
|
|
using /Zp), the output is :
|
|
|
|
Size of y = 3
|
|
Size of z = 3
|
|
|
|
Programs affected by this change should not mingle objects generated
|
|
by Versions 4.0 and 5.0. In such a case, you should recompile all of
|
|
the objects with Version 5.0 and higher. If that remedy is impossible
|
|
(for instance, if you do not have source code for the objects in
|
|
question), it is possible to change include files to add an extra
|
|
char-type member at the end of any odd-sized structure or union. This
|
|
change explicitly adds the alignment member that the compiler no
|
|
longer adds automatically.
|
|
|
|
|
|
105 /J Option
|
|
---------
|
|
When you invoke CL with the /J option, a new predefined identifier,
|
|
_CHAR_UNSIGNED, is defined. This identifier is used with #ifndef
|
|
in the file LIMITS.H to define the range of the default char type.
|
|
Note that compiling with /J reduces by one the number of constant and
|
|
macro definitions that you can give on the command line. The /J
|
|
option is not supported when using the /qc (QuickC) option of the
|
|
CL command (this is also true of the QCL driver for QuickC).
|
|
|
|
|
|
128 Passing Command-Line Data to a Program
|
|
--------------------------------------
|
|
The contents of the argv[0] string may be unpredictable in some
|
|
versions of DOS if you set all environment variables to null. (There
|
|
are few occasions when such an "empty environment" would be
|
|
appropriate. Since COMMAND.COM may need the COMSPEC variable, you
|
|
should normally define COMSPEC, at least.)
|
|
|
|
|
|
157 /NM Option
|
|
----------
|
|
The compiler uses the name of the file itself, not the name of the
|
|
module, in error messages. Furthermore, the effect of the /NM option
|
|
is now very limited. It only changes the name of the text segment in
|
|
a program with a large code segment _TEXT to <module>_TEXT. In a
|
|
small-model program, the /NM option has no effect.
|
|
|
|
|
|
130 Expanding Wild-Card Arguments
|
|
----------------------------
|
|
If you link your program with the SETARGV.OBJ file to expand
|
|
wild-card arguments, you must specify the /NOE linker option, which
|
|
tells the linker not to use the extended dictionary in searching
|
|
libraries. (See the description of the /NOE option under the heading
|
|
"Linker Options" later in this document.)
|
|
|
|
To compile a program WILDCARD.C that uses wild-card expansion, you can
|
|
use either this command:
|
|
|
|
CL wildcard.c \lib\setargv /link /NOE
|
|
|
|
or this command:
|
|
|
|
QCL wildcard.c \lib\setargv /link /NOE
|
|
|
|
This procedure is not necessary if you have used LIB to place the
|
|
wild-card expansion routines in the standard C combined library.
|
|
|
|
|
|
137 Segment Setup for Memory Models
|
|
-------------------------------
|
|
The primary segments of a C program are ordered in memory as shown
|
|
below, from the highest memory location to the lowest:
|
|
|
|
Segment Contents
|
|
------- --------
|
|
Heap Area of unallocated memory that is available for dynamic
|
|
allocation by the program. Its size varies, depending on
|
|
the program's other storage requirements.
|
|
|
|
STACK User's stack, used for all local data items
|
|
|
|
_BSS All uninitialized static data items except those that are
|
|
explicitly declared as far or huge.
|
|
|
|
c_common Uninitialized global data items for small- and medium-model
|
|
programs. In compact- or large-model programs, this type of
|
|
data item is placed in a data segment with class FAR\_BSS.
|
|
|
|
CONST Read-only constants, including floating-point constants,
|
|
string literals, and segment values for data items declared
|
|
far or huge or forced into their own segments by use of the
|
|
/Gt option.
|
|
|
|
_DATA Default data segment: this segment includes initialized
|
|
global and static data except data explicitly declared far
|
|
or huge, or data forced into different segments by use of
|
|
the /Gt option.
|
|
|
|
NULL Special-purpose segment at the beginning of DGROUP that
|
|
contains the compiler copyright notice. This segment is
|
|
checked before and after the program executes. If its
|
|
contents change during program execution, the program has
|
|
written to this area, usually by an inadvertent assignment
|
|
through a null pointer. Error message R6001 ("null pointer
|
|
assignment") appears to warn of this error.
|
|
|
|
Data Initialized static and global data items, placed in their
|
|
segments own segments with class name FAR_DATA, allowing the linker
|
|
to combine these items so that they precede DGROUP.
|
|
Uninitialized static and global far data items are placed
|
|
in segments that have class FAR_BSS, allowing the linker
|
|
to place these items between the _TEXT segment(s) and
|
|
DGROUP. Uninitialized huge items are placed in segments
|
|
with class FAR_DATA. In large- and huge-model programs,
|
|
global uninitialized data are treated as though declared
|
|
far (unless specifically declared near) and given class
|
|
FAR_BSS.
|
|
|
|
_TEXT In small and compact model, segment containing code for all
|
|
modules. In medium, large, and huge models, each module has
|
|
its own text segment with the name of the module plus the
|
|
suffix _TEXT.
|
|
|
|
When you look at a map file produced by linking a C program, you may
|
|
notice other segments in addition to the names listed below. These
|
|
additional segments have specialized uses for Microsoft languages and
|
|
should not be used by other programs.
|
|
|
|
|
|
159 The alloc_text Pragma
|
|
---------------------
|
|
No more than 10 alloc_text pragmas may appear in the same
|
|
compilation unit.
|
|
|
|
The alloc_text pragma MUST appear after the declarations of any
|
|
functions and before the definition of any functions given in the
|
|
pragma. Functions given in an alloc_text pragma may be implicitly near
|
|
(because the small or compact memory model is used) or explicitly near
|
|
(declared with the near keyword), provided that they are called only
|
|
by functions in the same segment.
|
|
|
|
Functions referenced in an alloc_text pragma should be defined in the
|
|
same module as the pragma. If this is not done, and an undefined
|
|
function is later compiled into a different text segment, the error
|
|
may or may not be caught. Although the program will usually run
|
|
correctly, the function is not allocated in the intended segments. The
|
|
following example shows code that may cause these problems:
|
|
|
|
Module 1
|
|
--------
|
|
#pragma alloc_text(SEG1, sample, example)
|
|
|
|
int sample(int i)
|
|
{
|
|
i = example(10);
|
|
}
|
|
|
|
Module 2
|
|
--------
|
|
int example(int i)
|
|
{
|
|
return(i*i);
|
|
}
|
|
|
|
You could prevent problems in the preceding code by placing the
|
|
definitions of the functions sample and example in the same module.
|
|
|
|
|
|
280 Limit on Nested Include Files
|
|
-----------------------------
|
|
The limit given for nested include files refers to the total number of
|
|
open files that the compiler allows. Since the original source file
|
|
counts as an open file, a total of nine files (in addition to the
|
|
original file) may have #include directives.
|
|
|
|
|
|
286 Increasing the Maximum Number of Open Files
|
|
-------------------------------------------
|
|
Version 5.10 allows you to increase the maximum number of open files
|
|
(the default number is 20). To use this feature, you must be running
|
|
OS/2 or DOS Version 3.3 (or later). Use the following procedure
|
|
to increase the maximum number of open files:
|
|
|
|
1. Increasing File Handles: To increase the number of file
|
|
handles, edit the startup source file CRT0DAT.ASM, which is
|
|
provided in this release. Change the line
|
|
|
|
_NFILE_ = 20
|
|
|
|
so that _NFILE_ is set to the desired maximum. For example, to
|
|
increase the maximum number of file handles to 40, change the
|
|
line as shown here:
|
|
|
|
_NFILE_ = 40
|
|
|
|
Increasing the number of file handles allows you to use low-
|
|
level I/O functions, such as open() and read(), with more files.
|
|
However, it does NOT affect the number of stream-level I/O
|
|
files (that is, the number of "FILE *" streams).
|
|
|
|
2. Increasing Streams: To increase the number of streams, edit
|
|
the source _FILE.C. Change the line
|
|
|
|
#define _NFILE_ 20
|
|
|
|
to set _NFILE_ to the desired maximum. For example, to allow a
|
|
maximum of 40 streams, change the line as shown here:
|
|
|
|
#define _NFILE_ 40
|
|
|
|
Increasing the number of streams allows you to use stream-level
|
|
I/O functions, such as fopen() and fread(), with more files.
|
|
|
|
Note that the number of low-level files MUST be greater than or
|
|
equal to the number of stream-level files. Thus, if you increase
|
|
the value of _NFILE_ in the module _FILE.C, you must also
|
|
increase the value of _NFILE_ in the module CRT0DAT.ASM.
|
|
|
|
3. Increasing the System Limit: To use more than 20 files at a
|
|
time, you must increase the file limit imposed on your process
|
|
by the operating system.
|
|
|
|
A. Increasing the System-Wide Limit: Increase the number of
|
|
files available on your system as a whole by editing your
|
|
system configuration file (for instance, CONFIG.SYS). For
|
|
example, to allow 100 files open at a time on your system,
|
|
put this statement in the configuration file:
|
|
|
|
FILES=100
|
|
|
|
B. Increasing the Per Process Limit: You must also increase the
|
|
number of files that the operating system makes available to
|
|
your particular process. To do this, edit CRT0DAT.ASM and
|
|
enable the commented-out code that is preceded by the
|
|
appropriate description before it.
|
|
|
|
In the DOS version of CRT0DAT.ASM, for example, the
|
|
commented-out code appears as shown here:
|
|
|
|
; mov ah,67h
|
|
; mov bx,_NFILE_
|
|
; callos
|
|
|
|
Remove the ';' comment characters.
|
|
|
|
4. Using the Modified Startup Files: After you modify CRT0DAT.ASM
|
|
and/or _FILE.C, assemble or compile the file(s). The startup
|
|
makefile contains sample command lines to perform these jobs.
|
|
|
|
To use the new objects, either explicitly link your program
|
|
with the new CRT0DAT.OBJ and _FILE.OBJ file(s), or replace
|
|
the CRT0DAT.OBJ and _FILE.OBJ object(s) in the appropriate
|
|
model of the C run-time library.
|
|
|
|
|
|
|
|
=========< Part 3: Notes for Microsoft C Run-Time Library Reference >==========
|
|
|
|
|
|
IMPORTANT: The memcpy function has been changed. It should no longer be used
|
|
to copy overlapping memory regions. See the note for page 421 in this Section
|
|
for more information about using memcpy.
|
|
|
|
|
|
The following notes refer to specific pages in the Microsoft C Optimizing
|
|
Compiler Run-Time Library Reference.
|
|
|
|
|
|
Page Note
|
|
---- ----
|
|
|
|
33 _amblksiz
|
|
---------
|
|
The _amblksiz variable has the type unsigned int, not int.
|
|
|
|
|
|
48 Hercules(R) Graphics
|
|
--------------------
|
|
This version of Microsoft C supports the Hercules(R) display adapter.
|
|
Below is a brief summary of this feature; see your Hercules
|
|
documentation for more details. Note that the graphics demonstration
|
|
program GRDEMO.C supports Hercules graphics.
|
|
|
|
Cards Supported
|
|
---------------
|
|
This version of Microsoft C supports the Hercules Graphics Card,
|
|
Graphics Card Plus, Incolor Card, and 100% compatibles.
|
|
|
|
Display Characteristics
|
|
-----------------------
|
|
Only monochrome (two-color) text and graphics are supported. The
|
|
screen resolution is 720 x 348 pixels in monochrome. The text
|
|
dimensions are 80 columns by 25 rows, with a 9 x 14 character box.
|
|
The bottom two scan lines of the 25th row are not visible.
|
|
|
|
The MSHERC.COM Driver
|
|
---------------------
|
|
You must load the Hercules driver MSHERC.COM before running your
|
|
program. Type MSHERC to load the driver. This can be done from an
|
|
AUTOEXEC.BAT file.
|
|
|
|
If you have both a Hercules monochrome card and a color video card,
|
|
you should invoke MSHERC.COM with the /H (/HALF) option. The /H
|
|
option causes the driver to use one instead of two graphics pages.
|
|
This prevents the two video cards from attempting to use the same
|
|
memory. You do not have to use the /H option if you have only a
|
|
Hercules card.
|
|
|
|
If you are developing a commercial application that uses graphics,
|
|
you should include MSHERC.COM with your product; you are free to
|
|
include this file without an explicit licensing agreement.
|
|
(MSHERC.COM is identical to QBHERC.COM, the Hercules driver
|
|
shipped with Microsoft QuickBASIC Version 4.0 and Microsoft BASIC
|
|
Compiler Version 6.0).
|
|
|
|
Using a Mouse
|
|
-------------
|
|
To use a mouse, you must follow special instructions for Hercules
|
|
cards in the Microsoft Mouse Programmer's Reference Guide. (This
|
|
must be ordered separately; it is not supplied with either
|
|
Microsoft C or the mouse package.)
|
|
|
|
Setting Hercules Graphics Mode
|
|
------------------------------
|
|
In the file GRAPH.H, note that the manifest constant _HERCMONO
|
|
sets the video mode to 720 x 348 monochrome for Hercules graphics,
|
|
and the constant _HGC has been added in the section "videoconfig
|
|
adapter values."
|
|
|
|
|
|
49 Alternate Text Heights
|
|
----------------------
|
|
The graphics library now functions correctly in 43-line mode on an EGA,
|
|
and 30-line, 43-line, 50-line, and 60-line modes on a VGA. In all video
|
|
modes, you should avoid mixing calls to the printf and _outtext
|
|
functions (use either printf or _outtext, but not both). The printf
|
|
function does not always handle scrolling correctly when the text
|
|
height has been changed.
|
|
|
|
Note that calling the _setvideomode function with the _DEFAULTMODE
|
|
parameter not only restores the original BIOS video mode, but also
|
|
restores the original text height.
|
|
|
|
|
|
51 Colors in Graphics and Text Modes
|
|
---------------------------------
|
|
In a color text mode (such as _TEXTC80), _setbkcolor accepts (and
|
|
_getbkcolor returns) an attribute, or pixel value. The value for the
|
|
default colors is given by the table in Section 4.4 of the QuickC
|
|
Programmer's Guide. For example, _setbkcolor(2L) sets the background
|
|
color to pixel value 2. The actual color displayed depends on the
|
|
palette mapping for pixel value 2. The default is green in a color
|
|
text mode.
|
|
|
|
In a color graphics mode (such as _ERESCOLOR), _setbkcolor accepts (and
|
|
_getbkcolor returns) a color (as used in _remappalette). The value for
|
|
the background color is given by the manifest constants defined in the
|
|
GRAPH.H include file. For example, _setbkcolor(_GREEN) sets the
|
|
background color in a graphics mode to green. These manifest constants
|
|
are provided as a convenience in defining and manipulating the most
|
|
common colors. The actual range of colors is, in general, much greater.
|
|
|
|
The function _setcolor accepts an int value as an argument. It is an
|
|
attribute or pixel value.
|
|
|
|
In general, whenever an argument is long, it refers to a color, and
|
|
whenever it is short, it refers to an attribute or pixel value. The two
|
|
exceptions are _setbkcolor and _getbkcolor described above.
|
|
|
|
|
|
61 Controlling Stream Buffering
|
|
----------------------------
|
|
The stdin, stdout, and stderr streams are buffered by default. The
|
|
stdout and stderr buffers are flushed whenever they are full, or, if
|
|
you are writing to a tty, after each library call. The stdprn and
|
|
stdaux streams are unbuffered by default.
|
|
|
|
|
|
93 The FLOAT.H File
|
|
----------------
|
|
To conform with the ANSI C standard, the following constants defined
|
|
in the include file FLOAT.H refer to a base-2 exponent in Version 5.10
|
|
of Microsoft C:
|
|
|
|
DBL_MIN_EXP
|
|
DBL_MAX_EXP
|
|
FLT_MIN_EXP
|
|
FLT_MAX_EXP
|
|
LDBL_MIN_EXP
|
|
LDBL_MAX_EXP
|
|
|
|
In Version 4.0, these constants refer to a base-10 exponent. The
|
|
base-10 versions of these constants are now named DBL_MIN_10_EXP,
|
|
DBL_MAX_10_EXP, and so on.
|
|
|
|
|
|
93 The GRAPH.H File
|
|
----------------
|
|
Several elements have been added to the GRAPH.H file in addition to
|
|
those mentioned in the manual. These include elements in the
|
|
videoconfig structure and manifest constants that allow you to test
|
|
the adapter and monitor information in the videoconfig structure. See
|
|
the current version of the GRAPH.H file for the most recent constant
|
|
names and definitions related to graphics functions.
|
|
|
|
|
|
114 alloca
|
|
------
|
|
When you compile with optimization on (either by default or by
|
|
using one of the /O options), the stack pointer may not be restored
|
|
properly in functions that have no local variables and also reference
|
|
the alloca function. This program demonstrates the problem:
|
|
|
|
/* Compile with CL /Lp /AM /Ox /Fc */
|
|
#include <malloc.h>
|
|
|
|
void main( void )
|
|
{
|
|
func( 10 );
|
|
}
|
|
|
|
void func( register int i )
|
|
{
|
|
alloca( i );
|
|
}
|
|
|
|
To ensure that the stack pointer is properly restored, you should
|
|
make sure that any function that references alloca declares at least
|
|
one local variable.
|
|
|
|
|
|
126 atof
|
|
----
|
|
In compact- and large-model programs, the string argument to the
|
|
atof function can be no longer than 100 characters.
|
|
|
|
|
|
128 bdos
|
|
----
|
|
Do not use the bdos, intdos, or int86 functions to call interrupts
|
|
that modify DS. Instead, use intdosx or int86x. Intdosx and int86x load
|
|
DS and ES from the "segregs" parameter, as documented, but they also
|
|
store DS and ES into "segregs" after the call.
|
|
|
|
|
|
138 _bios_keybrd, _bios_printer
|
|
---------------------------
|
|
The return value from the functions _bios_keybrd and _bios_printer
|
|
is of the type unsigned int.
|
|
|
|
|
|
174 cputs, fputs, puts
|
|
------------------
|
|
The return value from the cputs, fputs, or puts function is zero if the
|
|
function returns normally or a non-zero value if an error occurs.
|
|
|
|
|
|
179 ctime, gmtime, localtime, mktime
|
|
--------------------------------
|
|
Calls to the ctime and mktime functions modify the single statically
|
|
allocated buffer used by gmtime and localtime. Thus, a mktime or ctime
|
|
call destroys the results of any previous localtime or gmtime call.
|
|
|
|
The parameter to the localtime function is declared as
|
|
|
|
const time_t *time;
|
|
|
|
The information about the TZ environment variable should appear in the
|
|
description of the gmtime function, not the localtime function.
|
|
|
|
|
|
194 _dos_findfirst, _dos_findnext
|
|
-----------------------------
|
|
If the attributes argument to either of these functions is _A_RDONLY,
|
|
_A_HIDDEN, _A_SYSTEM, or _A_SUBDIR, the function also returns any
|
|
normal-attribute files that match the path argument (a normal file does
|
|
not have a read-only, hidden, system, or directory attribute).
|
|
|
|
|
|
208 _dos_open
|
|
---------
|
|
The argument to the _dos_open function should be *handle. The constant
|
|
O_RDONLY is defined in the file FCNTL.H, which you should include
|
|
when using O_RDONLY as the mode argument.
|
|
|
|
|
|
238 exec*, spawn* functions
|
|
-----------------------
|
|
Because of a bug in DOS Versions 2.0 and 2.1, child processes generated
|
|
by the exec* family of functions (or by the equivalent spawn* functions
|
|
with the P_OVERLAY argument) may cause fatal system errors when they
|
|
exit. If you are running DOS 2.0 or 2.1, you must upgrade to DOS
|
|
Version 3.0 to use these functions.
|
|
|
|
|
|
238 exec* functions
|
|
---------------
|
|
A program executed with one of the exec* family of C run-time functions
|
|
is always loaded into memory as if the "maximum allocation" field
|
|
in the program's .EXE file header is set to the default value of
|
|
0FFFFH. If you use the EXEMOD utility to change the maximum allocation
|
|
field of a program, the program behaves differently when invoked with
|
|
one of the exec* functions than when it is invoked directly from the
|
|
DOS command line or with one of the spawn* run-time functions.
|
|
|
|
|
|
277 FP_OFF, FP_SEG
|
|
--------------
|
|
The argument to these functions should be declared as a void far
|
|
pointer, not a char far pointer.
|
|
|
|
In models that use near data pointers (small and medium), the
|
|
FP_SEG and FP_OFF macros work only if the far-pointer argument is
|
|
stored in the default data segment. If the far pointer is stored in a
|
|
far data segment, the macros do not work correctly.
|
|
|
|
|
|
280 _fpreset
|
|
--------
|
|
In the example code, the second to last line should read
|
|
|
|
longjmp(mark, -1);
|
|
|
|
|
|
314 _getbkcolor
|
|
-----------
|
|
See note for page 51 above.
|
|
|
|
|
|
342 _getvideoconfig
|
|
---------------
|
|
In every text mode, including monochrome, the _getvideoconfig function
|
|
returns the value 32 for the number of available colors. The value 32
|
|
indicates the range of values (0 - 31) accepted by the _settextcolor
|
|
function. This includes sixteen normal colors (0 - 15) and sixteen
|
|
blinking colors (16 - 31). Blinking is selected by adding 16 to the
|
|
normal color value. Monochrome text mode has fewer unique display
|
|
attributes, so some color values are redundant. However, because
|
|
blinking is selected in the same manner, monochrome text mode has the
|
|
same range (0 - 31) as other text modes.
|
|
|
|
|
|
353 _heapchk
|
|
--------
|
|
In the example program, the statement
|
|
|
|
int heapstatus();
|
|
|
|
should read
|
|
|
|
int heapstatus;
|
|
|
|
|
|
365 int86, intdos, intdosx
|
|
----------------------
|
|
See note for page 128 above.
|
|
|
|
|
|
368 int86x
|
|
------
|
|
The "Return Values" section should refer to the cflag field in the
|
|
outregs union (not the flag field).
|
|
|
|
|
|
374 iscsym, iscsymf
|
|
---------------
|
|
The list of ctype routines should include the iscsym and iscsymf
|
|
routines, which test for the underscore (_) character. These routines
|
|
are defined in the CTYPE.H file.
|
|
|
|
|
|
410 malloc, _fmalloc, _nmalloc
|
|
--------------------------
|
|
The second paragraph under "Return Value" should read, "To get a
|
|
pointer to a type other than void, use a type cast on the return
|
|
value."
|
|
|
|
In the entry for malloc, delete the sentence that reads, "The
|
|
resulting pointer can be passed to the realloc function to adjust the
|
|
size at any time."
|
|
|
|
To ensure compatibility with a recent change to the ANSI C standard,
|
|
malloc(0) now returns a non-null pointer. In this regard, malloc works
|
|
the same way as in Microsoft C Version 4.0.
|
|
|
|
|
|
413 max
|
|
---
|
|
The example should not have a semicolon at the end of the line
|
|
containing main(). The body of the main function should be enclosed
|
|
in braces.
|
|
|
|
|
|
416 memccpy
|
|
-------
|
|
The dest and src arguments should have the type void *, not the type
|
|
const void *.
|
|
|
|
|
|
418 memchr
|
|
------
|
|
The c argument should have type int rather than size_t, and the count
|
|
argument should have type size_t rather than unsigned.
|
|
|
|
|
|
421 memcpy
|
|
------
|
|
The memcpy function does NOT ensure that overlapping regions of memory
|
|
are copied before they are overwritten. Use the memmove function
|
|
instead of memcpy to copy overlapping regions of memory.
|
|
|
|
If you need to ensure that memcpy exhibits its original behavior,
|
|
place the following #define directive in your source program:
|
|
|
|
#define memcpy(d,s,n) memmove(d,s,n)
|
|
|
|
|
|
426 memmove
|
|
-------
|
|
This function should be added to the list of functions that support
|
|
the use of huge pointers. The memmove function returns the value of
|
|
the dest parameter, not the src parameter.
|
|
|
|
|
|
429 min
|
|
---
|
|
The example should not have a semicolon at the end of the line
|
|
containing main(). The body of the main function should be enclosed
|
|
in braces.
|
|
|
|
|
|
444 open and sopen
|
|
--------------
|
|
Certain calls to the open or sopen function may set the global
|
|
variable errno to EINVAL. For instance, a call to sopen with an
|
|
invalid shflag argument (for example, 6) or a call to open with an
|
|
invalid oflag argument (for example, O_RDWR|O_WRONLY) returns a value
|
|
of -1 and sets errno to EINVAL.
|
|
|
|
|
|
461 printf
|
|
------
|
|
In Table R.3, the "Default" column for the "f" format type should
|
|
read as follows:
|
|
|
|
Default precision is 6; if precision
|
|
is 0 or the period (.) appears without
|
|
a number following it, no decimal point
|
|
is printed.
|
|
|
|
In the same table (R.3), in the "Default" column for the "g" format
|
|
type, the statement
|
|
|
|
All significant digits are printed.
|
|
|
|
should read
|
|
|
|
Six significant digits are printed, less
|
|
any trailing zeros that are truncated.
|
|
|
|
|
|
482 realloc
|
|
-------
|
|
The three paragraphs under "Return Value" should read as follows:
|
|
|
|
The realloc function returns a void pointer to the reallocated
|
|
memory block.
|
|
|
|
The return value is NULL if the size is zero and the buffer
|
|
argument is non-NULL, or if there is not enough available
|
|
memory to expand the block to the given size. In the first case,
|
|
the original block is freed. In the second, the original block
|
|
is unchanged.
|
|
|
|
To get a pointer to a type other than void, use a type cast
|
|
on the return value.
|
|
|
|
|
|
488 _remapallpalette, _remappalette
|
|
-------------------------------
|
|
The section "Return Value" should state that these functions return
|
|
a zero value when an error occurs, and non-zero when successful.
|
|
|
|
|
|
503 scanf
|
|
-----
|
|
This function no longer supports the D, O, X, and I type characters,
|
|
which represented long-integer input fields.
|
|
|
|
|
|
514 _setbkcolor, _setcolor
|
|
----------------------
|
|
See note for page 51 above.
|
|
|
|
|
|
523 setjmp
|
|
------
|
|
In the section "Return Value," the phrase
|
|
|
|
if the value argument of longjmp is 1, it returns 0
|
|
|
|
should read
|
|
|
|
if the value argument of longjmp is 0, it returns 1
|
|
|
|
|
|
525 _setlinestyle
|
|
-------------
|
|
In the section "Description," note that the default mask is
|
|
0xFFFF, not 0xFFF.
|
|
|
|
531 _settextcolor
|
|
-------------
|
|
See note for page 342 above.
|
|
|
|
|
|
537 setvbuf
|
|
-------
|
|
The setvbuf function can be used for an open stream only if you have
|
|
not yet been read from, or written to, that stream.
|
|
|
|
|
|
559 _splitpath
|
|
----------
|
|
The manifest constant shown as _MAX_NAME should be _MAX_FNAME. In
|
|
the example program for this function on page 560, the line
|
|
|
|
char * ext[4];
|
|
|
|
should read
|
|
|
|
char * ext[5];
|
|
|
|
|
|
584 strlen
|
|
------
|
|
The string parameter should have type const char * rather than char *.
|
|
|
|
|
|
598 strtod
|
|
------
|
|
In compact- and large-model programs, the string argument to the
|
|
strtod function can be no longer than 100 characters.
|
|
|
|
|
|
611 tmpnam
|
|
------
|
|
The description of this function under "Summary" should read "Create
|
|
temporary file in the directory defined by P-tmpdir." Also, the
|
|
sentence beginning "The tmpnam function uses malloc to allocate
|
|
space..." actually describes the tempnam function, not tmpnam.
|
|
|
|
|
|
624 ungetc
|
|
------
|
|
In the first paragraph under "Description," the second sentence
|
|
should read, "The stream must be open for reading."
|
|
|
|
|
|
|
|
|
|
==========< Part 4: Notes for the Microsoft C Language Reference >=============
|
|
|
|
The following notes refer to specific pages in the Microsoft C Optimizing
|
|
Compiler Language Reference.
|
|
|
|
Page Note
|
|
---- ----
|
|
|
|
76 Default Function Prototypes
|
|
---------------------------
|
|
When a call to a function precedes its declaration or definition,
|
|
a default function prototype is constructed. The default prototype has
|
|
the return type int, but the number and types of the actual arguments
|
|
are not used as the basis for declaring formal parameters. The
|
|
only way to ensure type checking of parameters is to use explicit
|
|
prototypes.
|
|
|
|
|
|
77 Parameter-Type Lists in Function Prototypes
|
|
-------------------------------------------
|
|
To conform with the ANSI standard, parameter-type lists in a function
|
|
prototype must match the corresponding function definition in types and
|
|
number of parameters and in the use of ellipsis terminators. Thus, code
|
|
such as the following, which was legal in Version 4.0, generates
|
|
warning messages in Version 5.10:
|
|
|
|
int func(int,...); /* prototype: ellipsis terminator */
|
|
|
|
int func(x, y, z) /* definition: no ellipsis terminator */
|
|
int x, y, z;
|
|
{
|
|
}
|
|
|
|
|
|
77 Defining Types in the Formal List of a Function
|
|
-----------------------------------------------
|
|
You cannot define a type within the formal list of a function. For
|
|
example, the following code is not acceptable:
|
|
|
|
void func( struct s { int a, b; } st );
|
|
|
|
void func( struct s st )
|
|
{
|
|
}
|
|
|
|
This rule applies to union and enumeration declarations as well as
|
|
structure declarations. Declare the type in conventional fashion,
|
|
outside the function's formal list.
|
|
|
|
The preceding code is acceptable under the ANSI standard, but the
|
|
type defined survives only to the closing parenthesis of the
|
|
prototype, and the closing brace (}) of the function definition.
|
|
Future versions of the Microsoft C Optimizing Compiler will treat
|
|
this code as an error.
|
|
|
|
|
|
77 Function Prototypes/Definitions with Float Arguments
|
|
----------------------------------------------------
|
|
In Version 4.0 of Microsoft C, the following code fragment apparently
|
|
specified a function that expected an argument of type float:
|
|
|
|
void takesfloat(float);
|
|
|
|
void takesfloat(f)
|
|
float f;
|
|
{
|
|
}
|
|
|
|
However, C as defined by Kernighan and Ritchie does not actually
|
|
support float (single-precision) arithmetic (unless double and float
|
|
are both single precision). Therefore, the argument was assumed to be
|
|
of the type double in both cases, and the compiler simply made the
|
|
change.
|
|
|
|
Under ANSI C, which specifically allows single-precision arithmetic,
|
|
you can pass single-precision actual arguments. However, a change
|
|
made to support this feature in Version 5.10 of Microsoft C may require
|
|
you to change existing code and recompile.
|
|
|
|
When compiled with Version 5.10, the preceding code fragment causes a
|
|
warning about a parameter mismatch between the prototype and the
|
|
definition of the takesfloat function. Although this is a warning
|
|
rather than an error, the resulting code DOES NOT work correctly.
|
|
|
|
The problem is that ANSI C considers old- and new-style function
|
|
definitions to be different. In particular, old-style definitions,
|
|
such as the definition in the preceding code, are forced to widen
|
|
type-float arguments to the type double. Thus, the example generates
|
|
a warning about a parameter mismatch because the prototype specifies
|
|
a type-float argument and the definition specifies a type-double
|
|
argument. However a new-style definition, such as the following,
|
|
accepts the narrower argument type:
|
|
|
|
void takesfloat(float f)
|
|
{
|
|
}
|
|
|
|
If you have code of this kind that causes parameter-mismatch problems,
|
|
you have two possible solutions, depending on whether the desired
|
|
argument type is actually float or double:
|
|
|
|
1. If you want type-double arguments, change argument types in the
|
|
prototype to double. (Also change the definition if you use the
|
|
/Zg option to generate the prototypes and you want to clarify
|
|
the change for anyone who reads the code later.)
|
|
|
|
2. If you want type-float arguments, change the definition to use
|
|
the new-style format shown above.
|
|
|
|
If the code must be portable to other (non-ANSI) C compilers, you must
|
|
use solution 1, since such compilers do not handle the new-style
|
|
definitions.
|
|
|
|
|
|
77 Return Type
|
|
-----------
|
|
If you use both QuickC and the C Optimizing Compiler, Version 5.0 and
|
|
higher, you should be aware of a difference in the values that each
|
|
compiler returns for a function declared as type float. QuickC
|
|
returns a float (4-byte real) value for such a function, while the
|
|
C Optimizing Compiler returns a double (8-byte real) value. This
|
|
difference causes problems if you mix QuickC and Version 5.x objects,
|
|
including libraries, in the same executable file.
|
|
|
|
The solution is to declare such return values as type double rather
|
|
than type float. For instance, the declaration
|
|
|
|
extern float func(float, double, int);
|
|
|
|
should appear as follows:
|
|
|
|
extern double func(float, double, int);
|
|
|
|
|
|
143 Converting unsigned long to double
|
|
----------------------------------
|
|
Unsigned values of the type long are now converted directly to type
|
|
double. They are not first converted to type long.
|
|
|
|
=================================< End >=======================================
|