Zio*_*yte 2 c gcc c-preprocessor
我面临一个奇怪的问题:
我有一个主要的开头:
#include <stdlib.h> /* this defines NULL */
#include <stdio.h> /* ditto */
#include <fcntl.h>
#include <ctype.h> /* ditto */
#include <unistd.h> /* ditto */
#include <linux/input.h>
#include <string.h> /* ditto */
#include <sys/ioctl.h>
#include "parse.h"
Run Code Online (Sandbox Code Playgroud)
...但在包含的文件中:
#define NULL ((void*)0) /* I need this! */
struct parse_key {
char *name;
unsigned int value;
} keynames[] = {
{"KEY_RESERVED", 0},
{"KEY_ESC", 1},
{"KEY_1", 2},
{"KEY_2", 3},
...
{"KEY_MAX", 0x2ff},
{NULL, 0}
};
Run Code Online (Sandbox Code Playgroud)
我需要重新定义NULL
,否则我得到错误:"错误:'NULL'在这里未声明(不在函数中)".
注:NULL
在主文件中定义; 如果我尝试#define
它,我得到:"警告:"NULL"重新定义"
修复是微不足道的,但我不明白发生了什么.有人会发光吗?
通常,当您在实际头文件中不包含必要的头文件时会发生此问题,但它们会在某些编译单元的头部之前包含在内.
即你没有必要的头文件#include
:
// parse.h
#ifndef PARSE_H
#define PARSE_H
struct parse_key
{
char *name;
unsigned int value;
}
static inline void key_init(struct parse_key * pk)
{
pk->name = NULL; // <-- you need it here
}
#endif // PARSE_H
Run Code Online (Sandbox Code Playgroud)
然后你有两个编译单元,但只有一个包含适当的标题:
// something.c
#include <stdlib.h>
#include "parse.h" // <-- preprocessor inserts this when NULL is already known
// something_else.c
#include "parse.h" // <-- but in this case, it will not compile
Run Code Online (Sandbox Code Playgroud)
唯一可靠的解决方案是在问题标题本身中包含所有必要的标题.
由于只编译.c文件,因此编译器不会关心.h文件中是否包含.c文件,但是在这些情况下,Visual Studio或Eclipse等IDE通常会显示警告消息.
作为旁注,这:
struct parse_key {
char *name;
unsigned int value;
} keynames[] = {
{"KEY_RESERVED", 0},
{"KEY_ESC", 1},
{"KEY_1", 2},
{"KEY_2", 3},
...
{"KEY_MAX", 0x2ff},
{NULL, 0}
};
Run Code Online (Sandbox Code Playgroud)
是一个变量,它将在包含头文件的每个编译单元中创建.这意味着您可能还会收到链接器错误,告诉您有重复的变量.
归档时间: |
|
查看次数: |
103 次 |
最近记录: |