KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q36782: C2086 Error When Compiling with /Oi and #include <mt\math.h>

Article: Q36782
Product(s): See article
Version(s): 5.10
Operating System(s): OS/2
Keyword(s): ENDUSER | | mspl13_c
Last Modified: 16-JAN-1990

When using the multithreaded version of <math.h>, error C2086
"identifier redefinition" occurs if -Oi (or -Ox) intrinsic
optimization is enabled. The cause of the error is the fact that the
compiler has built-in prototypes for intrinsic functions. Because
<mt\math.h> declares these functions differently, the C2086 error is
generated.

This conflict arises for the following floating-point routines:

   acos  asin  atan  atan2  cos  exp  fabs  fmod  log  log10  pow
   sin   sinh  sqrt  tan    tanh

The conflict occurs because the compiler has built-in function
prototypes for routines for which it is generating intrinsics. When
you compile with the normal include files, the compiler's internal
prototype is the same as the one in <math.h>, so there is no conflict.
However, when you use <mt\math.h>, the prototypes are changed from
"_CDECL" to "far pascal", which causes the redefinition error.

One workaround is to use the following

   #pragma function ({func1} {func2} {etc})

at the start of the module to force functions to be used instead of
intrinsics. This will also work if you are using the alternate math
library with multithreaded and/or DLL modules and the link fails with
unresolved externals.

A second workaround to this conflict is to use the C preprocessor's
conditional-compilation facility, as in the following fragment of
<mt\math.h>:

----------------------------------------------------------------------
    last part of <mt\math.h>
----------------------------------------------------------------------

/* function prototypes */

#ifndef INTRINSICS    /* this is the modification */

double far pascal acos(double);
double far pascal asin(double);
double far pascal atan(double);
double far pascal atan2(double, double);
double far pascal cos(double);
double far pascal cosh(double);
double far pascal exp(double);
double far pascal fabs(double);
double far pascal fmod(double, double);
double far pascal log(double);
double far pascal log10(double);
double far pascal pow(double, double);
double far pascal sin(double);
double far pascal sinh(double);
double far pascal sqrt(double);
double far pascal tan(double);
double far pascal tanh(double);

#endif  /* INTRINSICS; end of modification */

int    far _CDECL abs(int);
double far pascal atof(const char far *);
double far pascal cabs(struct complex);
double far pascal ceil(double);
int    far _CDECL dieeetomsbin(double far *, double far *);
int    far _CDECL dmsbintoieee(double far *, double far *);
int    far _CDECL fieeetomsbin(float far *, float far *);
double far pascal floor(double);
int    far _CDECL fmsbintoieee(float far *, float far *);
double far pascal frexp(double, int far *);
double far pascal hypot(double, double);
double far pascal j0(double);
double far pascal j1(double);
double far pascal jn(int, double);
long   far _CDECL labs(long);
double far pascal ldexp(double, int);
int    far _CDECL matherr(struct exception far *);
double far pascal modf(double, double far *);
double far pascal y0(double);
double far pascal y1(double);
double far pascal yn(int, double);

In this version of <mt\math.h>, the intrinsic math routines have been
pulled out of the main block of function prototypes and conditionally
compiled; the preprocessor will include them only if the symbol
"INTRINSICS" is not defined. This way, under normal circumstances,
nothing is different; when you #include <mt\math.h>, all the
prototypes are included. But when you want to optimize with /Ox or
/Oi, you can use the following command-line option so that the
preprocessor will remove those prototypes from the compilation:

cl  ... /D INTRINSICS ...

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.

Copyright Microsoft Corporation 1986-2002.