我保证在C语言中
small不是关键字,如果是关键字,在有或无
#include
指令的情况下都不会有任何区别。
问题在于
<windows.h>
愚蠢地将
small定义为宏。 (其他答案和评论表明它可能是
typedef
,但这并不能解释您看到的问题。)
我能够在我的系统上(Cygwin、Windows 7,使用
mingw32-gcc
编译,它作为Cygwin包的一部分安装)重现问题。假定从Cygwin单独安装MinGW也会发生同样的事情。
首先,
<conio.h>
是一个(非标准)由实现提供的头文件。你几乎肯定不应该尝试修改它。你绝对不应该在头文件中添加函数定义(函数定义应该放在
.c
文件中,而不是
.h
文件中)。如果你想编写自己的
gotoxy
函数,请在你自己的头文件中声明它,并在你自己的
.c
文件中定义它;不要玩弄实现。(B
但当你将你的
gotoxy
函数添加到
<conio.h>
时,你也添加了
这是一个小程序,用于说明问题:
#include <windows.h>
int main()
{
int small;
}
当我使用
mingw32-gcc
编译此程序时,会出现以下错误:
c.c: In function 'main':
c.c:4:9: error: two or more data types in declaration specifiers
c.c:4:5: warning: useless type name in empty declaration [enabled by default]
深入研究后,发现
<windows.h>
包括
<rpcndr.h>
,其中包含以下内容:
#define small char
在任何使用了
#include <windows.h>
的C源代码中,标识符
small
的每个出现都将被关键字
char
替换——在您的情况下,这将导致语法错误。一个方便的方法是使用
gcc
的
-E
选项,它可以显示编译器预处理阶段的输出。对于上面的程序,我尝试了这个选项。
$ mingw32-gcc -E c.c | tail
int main()
{
int char;
}
$
这段代码展示了预处理器如何破坏了int short;
的声明。
需要明确的是,这完全是<windows.h>
和<rpcndr.h>
维护人员的责任。 small
是一个完全有效的C标识符,系统头文件绝对不应将其定义为宏。 typedef char small;
可以达到相同的目的,而不会导致这个问题。其他人也遇到了类似的问题,例如 使用<windows.h>
时定义宏min
和max
。这可以通过以下方式解决:
据我所知,small
目前没有类似的解决方法。
顺便提一下,rpcndr.h
还定义了 hyper
。
最简单的解决方法是将变量命名为除 small
以外的其他名称,并希望不会与在 <windows.h>
中定义的其他宏发生冲突。或者您可以添加
#undef small
在声明之前,你不应该做这两件事情。但由于系统头文件编写不好的原因,有时候需要这样做来解决问题。如果可能的话,最好避免包含
<windows.h>
。你可以修改
rpcndr.h
文件,但我建议不要这样做;这很可能会导致其他问题,并且你的代码仍然无法在没有被篡改的
rpcndr.h
的系统上编译。更新:这个问题可能已经被修复了。我在Windows 10下的Cygwin上使用
x86_64-w64-mingw32-gcc
时没有看到错误。也许其他使用mingw的人可以进一步调查。
conio.h
,那么很可能你已经安装了VS,但CodeBlocks或实际上大多数IDE都允许你使用Ctrl + 单击单词以查看其定义…… - Elias Van Ootegemtypedef
不会引起这个问题,只有宏会。 - Keith Thompson