MSVC编译器中'inp'与'outp'为何被判定为已定义函数?
解决MSVC编译时
inp/outp标识符重定义与类型不匹配问题 问题背景
在Windows平台使用MSVC 19.38.33135 for x64编译可移植C编译器(pcc-revived)时,出现以下错误:
C:\work\pcc-revived\pcc\cc\cpp\cpp.h(176): error C2365: 'outp': redefinition; previous definition was 'function' C:\work\pcc-revived\pcc\cc\cpp\cpp.h(177): error C2365: 'inp': redefinition; previous definition was 'function'
同时,赋值语句pbeg = outp = inp = fb->buf;触发类型不匹配警告与左值错误:
..\..\cc\cpp\cpp.c(408): warning C4047: '=': 'int (__cdecl *)()' differs in levels of indirection from 'usch *' ..\..\cc\cpp\cpp.c(408): error C2106: '=': left operand must be l-value
代码中cpp.h的相关声明:
typedef char usch; extern char *pbeg; extern char *pend; extern char *outp; extern char *inp;
问题根源
MSVC编译器对inp和outp有内置的隐式函数声明——这两个是Win16时代遗留的端口I/O函数(原本用于读写硬件端口),即使没有包含任何Windows SDK头文件,MSVC也会自动将它们识别为返回int的函数原型,导致和代码中声明的char*类型变量冲突,触发重定义错误。而当尝试给函数指针赋值时,自然会出现类型不匹配和左值错误。
验证点:将outp/inp改名为outpx/inpx后编译正常,说明问题完全来自标识符本身的保留属性,而非外部头文件引入的定义。
解决方案
方案1:重命名标识符(推荐)
直接修改代码中所有outp和inp的引用,替换为未被MSVC保留的标识符,比如out_ptr、in_ptr:
- 修改
cpp.h:extern char *out_ptr; extern char *in_ptr; - 修改
cpp.c中的赋值语句:pbeg = out_ptr = in_ptr = fb->buf;
这种方法彻底避免了标识符冲突,不会引入任何编译器依赖的设置。
方案2:禁用MSVC的内置隐式声明
通过编译器选项取消MSVC对inp/outp的内置识别:
- 方法一:在Visual Studio项目属性中,进入「C/C++ -> 预处理器 -> 预处理器定义」,添加
_NO_INP_OUTP宏(MSVC提供的专门禁用这两个函数隐式声明的宏)。 - 方法二:在编译命令中直接添加参数:
/Uinp /Uoutp,强制取消编译器对这两个标识符的内置定义。
内容的提问来源于stack exchange,提问作者pm100
相关产品推荐
相关产品推荐

