gpt4 book ai didi

c - #include 指令是否在宏扩展之前处理,而不管它们在文件中的位置如何?

转载 作者:行者123 更新时间:2023-12-04 02:56:39 25 4
gpt4 key购买 nike

前几天我遇到了一些类似于以下的代码(为简洁起见,以下内容已经过分简化):

config.h

#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。当我这样做时,我收到以下错误:

警告 553:未定义的预处理器变量“_TRUE_”,假定为 0

然后我想知道为什么编译器没有捕捉到 _TRUE_ 是在 my_defs.h 中定义的,它包含在宏第一次使用之后。所以我在不同的编译器上编译它并得到相同的结果 - 编译成功,没有警告并且 FILE_NAME 被正确评估,无论我如何设置 DEVELOPMENT_BLD(使用 _TRUE_!_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 的实际值是多少。我运行了两次以下代码:

ma​​in.c

#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"。然后我开始收到编译器错误:

错误:“_TRUE_”未声明(首次在此函数中使用)

所有这些都引出了我的问题。 #include 语句是否需要在宏扩展之前由预处理器评估,还是我只是走运?

最佳答案

C 预处理器在遇到指令时对其进行操作。在这种情况下,警告是正确的;在您使用 #if DEVELOPMENT_BUILD == _TRUE_ 时,_TRUE_ 的有效值为零。但是,由于 #define DEVELOPMENT_BUILD _TRUE_ 定义,预处理器正在评估 #if 0 == 0,这是正确的。但是,如果您指定了 #define DEVELOPMENT_BUILD _FALSE_,您会得到相同的结果,因为 _FALSE_ 也将隐式为 0,因此测试将是 # if 0 == 0 再次(它的计算结果也为真)。如果当预处理器完成对 #if 条件中的表达式求值时,还有剩余的标识符,它们将被隐式假定为 0。

请注意,以下划线和大写字母或其他下划线开头的名称保留供实现使用。您选择的名称如 _TRUE___CONFIG__ 是如履薄冰。 (仅仅因为系统头使用这样的名称并不是你这样做的好理由——事实上,恰恰相反。系统头小心地远离为你保留使用的命名空间;你应该远离命名空间为系统保留。)

关于c - #include 指令是否在宏扩展之前处理,而不管它们在文件中的位置如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16576415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com