BUG: Incorrect Cast from Near to Far Function PointerLast reviewed: July 22, 1997Article ID: Q116243 |
7.00 | 1.00 1.50
MS-DOS | WINDOWS
kbtool kbbuglist
The information in this article applies to:
SYMPTOMSThe 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.
CAUSEThis 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.
RESOLUTIONThere 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.
STATUSMicrosoft 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 INFORMATIONThe 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
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |