Microsoft KB Archive/38729

From BetaArchive Wiki

PRB: Floats Promoted to Doubles w/ Old Style Function Declare

Article ID: Q38729

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE) included with: - Microsoft C for MS-DOS, versions 6.0, 6.0a, 6.0ax - Microsoft C for OS/2, versions 6.0, 6.0a - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, versions 1.0, 1.5 - Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 4.0, 5.0

SYMPTOMS

Using old style function declarations causes the compiler to promote floats to doubles.

MORE INFORMATION

For example, even though the following functions are both expecting two floats as parameters, the compiler will promote the floats passed to function BBB to doubles.

   float AAA(float x1, float x2)
   {
       x1 = x2;
   }

   float BBB(x1,x2)
   float x1,x2;
   {
       x1 = x2;
   }

When the functions shown above are compiled with the /Zg switch, which generates function prototypes, the following prototypes are generated:

   extern  float AAA(float x1, float x2);
   extern  float BBB(double x1, double x2);

The following is from the May 5, 1988 ANSI draft, Section 3.3.2.2:

   If the expression that denotes the called function has a type that
   does not include a prototype...arguments that have type float are
   promoted to double.

   If the expression that denotes the called function has a type that
   includes a prototype, the arguments are implicitly converted, as if
   by assignment, to the types of the corresponding parameters.

Function AAA, uses the newer function definition style. Note that if this function is called (perhaps from another module) without a prototype in scope, there will be problems because the compiler will pass doubles rather than floats (see first paragraph above). Function BBB uses the old style of definition as described in Kernighan and Ritchie (K & R). Because K & R specified that floats are to be widened to doubles when they're passed to functions (and in a variety of other situations as well), the old style declarations maintain the old semantics.

Therefore, the /Zg switch is correctly generating the function prototypes.

A program wouldn't run correctly if it declared the following prototype before calling BBB because the prototype that was in scope when it CALLED BBB does not match the implicit prototype generated when the function was defined:

   void BBB(float, float);

As a result, floats are passed to a function that was expecting doubles. Additional query words: 8.00 8.00c 9.00

Keywords          : kbCompiler 
Version           : 6.0 6.0a 6.0ax 7.0 1.0 1.5 2.0 4
Issue type        : kbprb

Last Reviewed: July 26, 1997
© 1999 Microsoft Corporation. All rights reserved. Terms of Use.