c - "small"是c 中的关键字吗?

标签 c header-files identifier

这是第一个代码

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

这是第二个代码

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

每当我包含头文件时 <conio.h>然后声明标识符“small”会出错,为什么? 我正在使用 mingw gcc编译器和 codeblocks想法

我还在 <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);
}

<conio.h> 中删除上述代码后

int small;

即使在包含 <conio.h> 之后仍然有效.

最佳答案

我保证small 不是 C 中的关键字。如果是,#include 是否存在指令不会有任何区别。

问题是 <windows.h>愚蠢地定义small作为宏。 (其他答案和评论表明它可能是 typedef ,但这并不能解释您所看到的问题。)

我能够在我的系统上重现该问题(Cygwin、Windows 7,使用 mingw32-gcc 编译,作为 Cygwin 软件包的一部分安装)。如果 MinGW 与 Cygwin 分开安装,大概也会发生同样的事情。

首先,<conio.h>是实现提供的(非标准) header 。您几乎肯定不应该尝试修改它。您绝对不应该将函数定义添加到头文件(函数定义属于.c 文件,而不是.h 文件)。如果你想自己写gotoxy函数,在你自己的header中声明,在你自己的.c中定义文件;不要搞乱实现。 (B

但是当你添加你的 gotoxy功能<conio.h> , 你还添加了

#include <windows.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

因此每次出现标识符 small在任何具有 #include <windows.h> 的 C 源代码中将被关键字 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;
}
$ 

这显示了 int short;声明被预处理器破坏了。

需要说明的是,这完全是 <windows.h> 维护者的错和 <rpcndr.h> . small是完全有效的 C 标识符,系统头文件绝对不应将其定义为宏。 typedef char small;本来可以达到同样的目的,不会引起这个问题。其他人有similar problems<windows.h>定义宏 minmax .这可以解决:

#define NOMINMAX
#include <windows.h>

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

顺便说一句,rpcndr.h还定义了 hyper .

最简单的解决方案是将变量命名为 small 以外的名称-- 并希望您不会与 <windows.h> 中定义的其他宏发生冲突.或者你可以添加

#undef small

声明之前。您不应该需要做这些事情中的任何一个,但由于系统头文件编写不当,有时需要这样的解决方法。

或者只是避免包含 <windows.h> (这并不总是可能的)。

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

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

关于c - "small"是c 中的关键字吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21165891/

相关文章:

c - 在 Visual Studio 中构建大量小工具有什么好方法?

编译器需要在第一列添加 # 吗?

c++ - 定位/下载头文件 R.h 和 Rmath 用于 C 与 R 接口(interface)

c++ - 编译错误: solution.c:20:5: error: expected identifier or ‘(’ before ‘{’ token {

c++ - 编译器循环引用

c - 获取内存在 NUMA 中的位置

c++ - 了解 Google 的 C++ 风格指南的 #include 顺序指南的 "build break"基本原理

C++ #ifndef 对于包含文件,为什么头文件全部使用大写?

mysql - Hibernate 标识符名称对于 MySQL 索引来说太长

javascript - 从javascript中的JSON子数组中检索数据,其中标识符以整数开头