ID: Q116243
7.00 | 1.00 1.50 MS-DOS | WINDOWS kbtool kbbuglist
The information in this article applies to:
- Microsoft C/C++ for MS-DOS, version 7.0
- Microsoft Visual C++ for Windows, versions 1.0 and 1.5
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.
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.
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.
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.
The following sample code can be used to demonstrate this problem:
/* 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
Last Reviewed: July 23, 1997