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

Last reviewed: July 24, 1997
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 : CLIss kbfasttip
Version : 6.0 6.0a 6.0ax 7.0 1.0 1.5 2.0 4
Issue type : kbprb


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

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