BUG: Incorrect Cast from Near to Far Function Pointer

Last reviewed: July 22, 1997
Article ID: Q116243
7.00 | 1.00 1.50 MS-DOS | WINDOWS kbtool kbbuglist

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE) included with:

        - Microsoft C/C++ for MS-DOS, version 7.0
        - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    

SYMPTOMS

The code listed below should cause the compiler to return error message C2187: "Cast of near function pointer to far function pointer." Instead, incorrect code is generated that loads the segment of the far function pointer with DS, the data segment, rather than with the correct code segment.

CAUSE

This condition is not correctly caught in the initial stage and code generation continues, where the far function pointer is treated as a data address and the address is extended using the data segment.

RESOLUTION

There is no direct workaround, so assignments that convert near and far pointers to functions (function addresses) should be avoided. In addition, because the function is near, the return instruction generated is also near. If the function pointer is correctly cast to be far, both CS and IP are pushed on the stack during a function call. The near return only pops IP, causing stack corruption and causing execution to continue in an incorrect location.

STATUS

Microsoft has confirmed this to be a bug in the C/C++ compiler for MS-DOS, versions 7.0, 8.0, and 8.0c. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

This problem does not occur in the 32-bit C/C++ compiler, because there are no near and far pointers in flat addressing.

MORE INFORMATION

The following sample code can be used to demonstrate this problem:

Sample Code

/* Compile options needed: /c /Gs /f- /Fc
*/

   #include <stdio.h>
   #include <dos.h>

   typedef void (__far *FARFUNCPTR)(void) ;
   typedef void (__near *NEARFUNCPTR)(void) ;

   void hfunc (void) { return; }
   FARFUNCPTR install (NEARFUNCPTR) ;

   FARFUNCPTR install (NEARFUNCPTR handler)  {
      return (FARFUNCPTR)handler;
   }

   int main (void) {

       FARFUNCPTR fptr ;

       printf("CS= %04x\nDS= %04x\n", __segname("_CODE"),
   __segname("_DATA"));
       fptr= install(hfunc);
       printf("Install %Fp\n", fptr);
       fptr= (FARFUNCPTR) hfunc ;
       printf("Direct %Fp\n",fptr);

       return (0);
   }

//This is the portion of the /Fc compiler listing that illustrates the
//incorrect use of DS as the segment of the far function pointer:

   ;|***      return (FARFUNCPTR)handler;
   ; Line 20
   *** 00001b     8b 46 04           mov     ax,WORD PTR
    [bp+4]     ;handler
   *** 00001e     8c da                mov     dx,ds
   *** 000020     e9 00 00           jmp     $EX221


Additional reference words: 1.00 1.50 7.00 8.00 8.00c
KBCategory: kbtool kbbuglist
KBSubCategory: CodeGen
Keywords : kb16bitonly


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 22, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.