首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果Enum是编译时间,那么#define是如何工作的?

如果Enum是编译时间,那么#define是如何工作的?
EN

Stack Overflow用户
提问于 2019-10-14 11:54:04
回答 2查看 95关注 0票数 0

根据This question,首先对预处理器进行评估,然后对枚举进行处理.我查过了而且是真的!

我有一个Enum eTypes

代码语言:javascript
复制
typedef enum
{
   eTYPE_1 = 0u,
   eTYPE_2,
   eTYPE_3,
   eTYPE_MAX
} eTypes;

然后我将大小定义为

#define MAX_ARRAY_SIZE (2 * eTYPE_MAX)

并将数组声明为U8 TestArray[MAX_ARRAY_SIZE]

根据链接问题,在处理MAX_ARRAY_SIZE时,编译器不知道eTypes。那么TestArray如何获得正确的大小。我看到了6个字节的TestArray。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-14 11:57:39

预处理程序执行简单的文本替换(*)

代码语言:javascript
复制
U8 TestArray[MAX_ARRAY_SIZE]

代码语言:javascript
复制
U8 TestArray[(2 * eTYPE_MAX)]

然后由编译器处理。编译器将在编译时计算常量值2 * eTYPE_MAX,这将导致2 * 3 = 6

(*)更正确的是,由预处理程序和编译器处理源代码要复杂一些。预处理程序处理标记,而不是输入文本的随机部分。参见例如https://stackoverflow.com/a/52468676/10622916

问题的要点是,预处理器并不关心替换文本中的eTYPE_MAX是否是enum值,即使替换是有效的C代码也不关心。

票数 6
EN

Stack Overflow用户

发布于 2019-10-14 12:10:21

根据链接问题,在处理MAX_ARRAY_SIZE时,编译器不知道eTypes。那么TestArray如何获得正确的大小。我看到了8个字节的TestArray。

嗯,不是。你似乎误解了the accepted answer to that question的这句话

--在编译器了解有关enum的任何信息之前,预处理器就会运行。预处理器只知道宏(#define)。

预处理器不将枚举常量识别为不同于任何其他标识符,但编译器当然知道它们,只要枚举声明在作用域中。在实践中,这两种工具通常都驻留在同一个程序中并在其中运行,这一点并不令人困惑。

另一个问题是,涉及枚举常数的表达式是否被视为编译时常数,但标准答案显然是:

整数常量表达式应具有整数类型,并且只能具有操作数,即整数常量、枚举常数、字符常量、结果为整数常量的表达式的大小、_Alignof表达式和浮点常量,它们是转换的直接操作数。整数常量表达式中的强制转换运算符只应将算术类型转换为整数类型,但作为操作数的一部分,则应转换为sizeof of或_Alignof运算符。

(C2011,6.6/6)

“整数常量表达式”是普通数组的维数所需的类型(相对于可变长度数组而言)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58376231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档