前几天我遇到了一些类似于以下的代码(为简洁起见,以下已被过度简化):
配置文件
#ifndef __CONFIG__
#define __CONFIG__
#define DEVELOPMENT_BLD _TRUE_
#if (DEVELOPMENT_BLD == _TRUE_)
#define FILE_EXT ".dev"
#else
#define FILE_EXT ".bin"
#endif
#define PROJECT_STRING "my_project"
#define FILE_NAME PROJECT_STRING FILE_EXT
/* Common include files */
#include "my_defs.h"
#endif /* __CONFIG__ */
my_defs.h
#ifndef __MY_DEFS__
#define __MY_DEFS__
#define _TRUE_ 1
#endif /* __MY_DEFS__ */
该项目一直编译没有任何问题,但由于我做了一些小改动(而且实际项目相当大),我决定在其上运行 Lint。当我这样做时,我收到以下错误:
Warning 553: Undefined preprocessor variable '_TRUE_', assumed 0
然后我想知道为什么编译器没有捕获_TRUE_
my_defs.h 中定义的内容,该文件包含在宏第一次使用之后。所以我在不同的编译器上编译了它,结果相同——编译成功,没有警告,并且FILE_NAME
无论我如何设置DEVELOPMENT_BLD
(使用_TRUE_
or !_TRUE_
)都得到了正确的评估。这是我的两个编译器设置:
ArmCC -c -cpu Cortex-M3 -g -O0 --apcs=interwork -I "..\ARM\CMSIS\Include" -I "..\ARM\INC\NXP\LPC17xx" -o "file.o" --omf_browse "file.crf" --depend "file.d" "file.c"
mingw32-gcc.exe -pedantic -Wall -g -c D:\dev\practice\header_question\main.c -o obj\Debug\main.o
我决定运行一个简单的测试,看看FILE_NAME
预处理器是否正确评估了 的值。我还想看看实际的价值是多少DEVELOPMENT_BLD
。我运行了以下代码两次:
主程序
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("FILE_NAME:%s, WHAT_IS_TRUE:%d", FILE_NAME,DEVELOPMENT_BLD);
return 0;
}
我第一次使用#define DEVELOPMENT_BLD _TRUE_
这个结果的值:
FILE_NAME:my_project.dev, WHAT_IS_TRUE:1
我第二次使用#define DEVELOPMENT_BLD !_TRUE_
这个结果的值:
FILE_NAME:my_project.bin, WHAT_IS_TRUE:0
我的第一个想法是,这可能_TRUE_
是在其他地方定义的——所以只是为了确保我注释掉了#include "my_defs.h"
。然后我开始收到编译器错误:
error: '_TRUE_' undeclared (first use in this function)
所有这些都引出了我的问题。#include 语句是否需要在宏扩展之前由预处理器评估,还是我只是幸运?