繁体   English   中英

C宏是否隐式投射?

[英]Are C macros implicitly cast?

我搜索了SO,但没有找到这个具体问题的答案。 请原谅我已经回答了。

如果您有以下内容:

#define MACRO  40

您不将它分配给在循环中使用它的变量:

for(int i = 0; i < MACRO; i++) {...

然后,每个处理器创建:

for(int i = 0; i < 40; i++) {...

然后编译器会将它隐式地转换为int,因为比较是使用int i类型吗? 我看过这个问题#define变量的类型 ,而Edgar Bonet的一些答案暗示了编译器选择如何处理宏的顺序?

这个问题, C ++如何隐式地将参数转换为比较器,如<? ,也有人建议,但只描述了隐式转换如何与两种类型进行比较。 由于宏实际上没有类型,我不确定这是否适用。

在C和C ++中,宏实际上是就地替换。 预处理器将遇到这些#define并在找到它们时替换它们。 这就是你可以在宏中嵌套宏的方法,它只需要1个传递来预处理。

预处理器在编译器甚至看到任何内容之前扩展宏。 我们可以看到预处理数字没有类型,可以通过草案C99标准部分6.4.8 预处理数字说:

预处理号码没有类型或值; 它在成功转换(作为转换阶段7的一部分)之后获取浮动常量令牌或整数常量令牌。

C ++标准草案中的相同部分是2.10

正如我们在C预处理器Wikipedia中看到的那样,宏扩展发生在第4阶段。

C语言中的整数常量转换和C ++术语中的整数文字在C99标准部分6.4.4.1 整数常量和第5段中的下表中有所说明:

整数常量的类型是相应列表中可以表示其值的第一个

Octal or Hexadecimal
Suffix        Decimal Constant                 Constant
---------------------------------------------------------------------------
none          int                           int
              long int                      unsigned int
              long long int                 long int                                
                                            unsigned long int
                                            long long int
                                            unsigned long long int
---------------------------------------------------------------------------
u or U        unsigned int                  unsigned int
              unsigned long int             unsigned long int
              unsigned long long int        unsigned long long int
---------------------------------------------------------------------------
l or L        long int                      long int
              long long int                 unsigned long int
                                            long long int
                                            unsigned long long int
---------------------------------------------------------------------------
Both u or U   unsigned long int             unsigned long int
and  l or L   unsigned long long int        unsigned long long int
---------------------------------------------------------------------------
ll or LL      long long int                 long long int
                                            unsigend long long int
---------------------------------------------------------------------------
Both u or U   unsigned long long int        unsigned long long int
and  ll or LL
---------------------------------------------------------------------------

表是此答案的修改版本。 C ++标准草案中涉及此部分的部分是第2.14.2节,其中也有类似的表。

因此,在您的示例中, 40没有后缀并且是十进制常量,并且可以从表的该部分表示的第一个类型是int

此时,我们现在最终得到了使用40<运算符的效果。 由于i40都是算术类型 ,因此将执行通常的算术转换,在这种情况下仍然是int 对于C99,这将在6.3.1.8和C ++第56.3.1.8介绍。

C宏只是文本替换,它们没有类型。 涉及类型的所有内容都是宏替换之后完成的其行为与您在原始代码中键入替换内容的行为相同。

编译器永远不会看到宏; 预处理器在源文本输入编译器之前扩展所有宏。

所有编译器都看到了

for(int i = 0; i < 40; i++) {...}

并且,常量表达式40的类型是基于2011 C标准的 6.4.4.1节或在线C ++标准的 2.13节中的规则确定的。

C宏中只是替换文本,这意味着宏表示的文本被复制而不是宏名称,您甚至可以将C关键字放在宏中。

#define [identifier name] [value]

在代码中, 标识符名称替换。 你的定义是:

#define MACRO  40

40已经是一个int。 所以for(int i = 0; i < 40; i++)不需要演员表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM