C宏是否隐式投射?

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

如果您有以下内容:

#define MACRO 40 

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

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

然后,perprocessor创建:

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

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

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

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

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

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

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

C99术语中的整数常量转换和C ++术语中的整数文字包含在草案C99标准部分6.4.4.1 整数常量和第5段中的下表中,其中说明:

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

                                           八进制或hex
后缀十进制常量
 -------------------------------------------------- -------------------------
 none int int
               long int unsigned int
               long long int long int                                
                                             unsigned long int
                                             long long int
                                             unsigned long long int
 -------------------------------------------------- -------------------------
 u或U unsigned int unsigned int
               unsigned long int unsigned long int
               unsigned long long int unsigned long long int
 -------------------------------------------------- -------------------------
 l或L long int long int
               long long int unsigned long int
                                             long long int
                                             unsigned long long int
 -------------------------------------------------- -------------------------
 u或U unsigned long int unsigned long int
和l或L unsigned long long int unsigned long long int
 -------------------------------------------------- -------------------------
 ll或LL long long int long long int
                                            无长期的长期
 -------------------------------------------------- -------------------------
 u或U unsigned long long int unsigned long long int
和ll或LL
 -------------------------------------------------- -------------------------

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

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

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

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

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++)不需要演员表。