"小"是c中的关键字吗?

4 c identifier header-files

这是第一个代码

#include <stdio.h>
#include <conio.h>
int main()
{
    int small;//showing error-(two or more data type in declaration specifiers
}
Run Code Online (Sandbox Code Playgroud)

这是第二个代码

#include <stdio.h>
int main()
{
    int small;//normal declaration without any error
}
Run Code Online (Sandbox Code Playgroud)

每当我包含头文件,<conio.h> 然后声明标识符"小"会出错,为什么?我正在使用mingw gcc编译器和codeblockside

我还添加了以下代码 <conio.h>

#include <windows.h>
void gotoxy(short int col,short int row)
{
    HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
    COORD position={col,row};
    SetConsoleCursorPosition(hStdout,position);
}
Run Code Online (Sandbox Code Playgroud)

从上面删除上面的代码后 <conio.h>

int small;
Run Code Online (Sandbox Code Playgroud)

包括后甚至工作<conio.h>.

Kei*_*son 8

我保证,small不是在C关键字如果是这样,一个的存在或不存在#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>
Run Code Online (Sandbox Code Playgroud)

这是一个说明问题的小程序:

#include <windows.h>
int main()
{
    int small;
}
Run Code Online (Sandbox Code Playgroud)

当我编译它时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]
Run Code Online (Sandbox Code Playgroud)

进一步挖掘,结果是<windows.h>包括<rpcndr.h>,其中包含以下内容:

#define small char
Run Code Online (Sandbox Code Playgroud)

因此small,任何C源中的标识符的每次出现都#include <windows.h>将被关键字替换char- 在您的情况下,将导致语法错误.

找到这样的东西的一种方便的方法:gcc有一个-E选项,使它显示编译器的预处理器阶段的输出.通过上面的程序,我尝试了这个:

$ mingw32-gcc -E c.c | tail



#pragma pack(pop)
# 115 "c:\\gnustep\\bin\\../lib/gcc/mingw32/4.6.1/../../../../include/windows.h" 2 3
# 2 "c.c" 2
int main()
{
    int char;
}
$ 
Run Code Online (Sandbox Code Playgroud)

它显示int short;了预处理器如何破坏声明.

需要明确的是,这是完全的维护人员的故障<windows.h><rpcndr.h>.small是一个完全有效的C标识符,系统头绝对不应该将其定义为宏.typedef char small;会产生同样的目的而不是造成这个问题.其他有类似问题<windows.h>定义的宏minmax.这可以解决:

#define NOMINMAX
#include <windows.h>
Run Code Online (Sandbox Code Playgroud)

但据我所知,没有这样的解决办法small.

顺便提一下,rpcndr.h也定义了hyper.

最简单的解决方案是调用你的变量而不是small- 并希望你不要与其中定义的其他宏发生冲突<windows.h>.或者你可以添加

#undef small
Run Code Online (Sandbox Code Playgroud)

宣言之前.您应该执行上述任何一项操作,但由于编写的系统标头写得不好,有时需要这样的解决方法.

或者只是避免包括<windows.h>(这并非总是可行).

(您可以修改您的rpcndr.h文件副本,但我建议不要这样做;它可能会导致其他问题,并且您的代码仍然无法在rpcndr.h未被黑客攻击的系统上编译.)

更新:这可能已得到纠正.我没有x86_64-w64-mingw32-gcc在Windows 10上看到使用Cygwin下的错误.也许使用mingw的其他人可以进一步调查.