我搜索了SO,但没有找到这个具体问题的答案。请原谅我,如果它已被回答。
如果您有以下内容:
#define MACRO 40
您不会将它分配给在循环中使用它的变量:
for(int i = 0; i < MACRO; i++) {...
然后,每个处理器创建:
for(int i = 0; i < 40; i++) {...
编译器是否会将其隐式地转换为int,因为比较是使用类型int i
?我看过这个问题Type of #define variables,Edgar Bonet下的一些答案意味着编译器选择如何处理宏的顺序?
还提出了这个问题How does C++ implicitly cast arguments to a comparator such as <?,但仅描述了隐式转换如何与两种类型进行比较。由于宏实际上没有类型,我不确定这是否适用。
答案 0 :(得分:9)
在C和C ++中,宏实际上是就地替换。预处理器将遇到这些#define
并在找到它们时替换它们。这就是你可以在宏中嵌套宏的方法,它只需要1个传递来预处理。
答案 1 :(得分:8)
preprocessor在编译器看到任何内容之前扩展宏。我们可以看到预处理数字没有类型,只需转到draft C99 standard部分6.4.8
预处理数字,其中包含:
预处理号码没有类型或值;它获得了两者 成功转换(作为翻译阶段7的一部分)到a 浮动常量标记或整数常量标记。
C ++标准草案中的同一部分是2.10
。
正如我们在C preprocessor Wikipedia article中看到的那样,宏扩展发生在第4阶段。
草案C99标准部分6.4.4.1
整数常量和 5 < / em>其中说:
整数常量的类型是相应列表的第一个 其值可以表示
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 ---------------------------------------------------------------------------
表是此answer的修改版本。 C ++标准草案中涉及此部分的部分是2.14.2
部分,它也有类似的表格。
因此,在您的示例中,40
没有后缀并且是十进制常量,并且可以从表的该部分表示的第一种类型是 int 。
此时,我们现在最终将40
与<
运算符结合使用。由于i
和40
都是算术类型,因此将执行通常的算术转换,在这种情况下仍将是 int 。对于 C99 ,这将在6.3.1.8
部分和C ++部分 5 中介绍。
答案 2 :(得分:5)
C宏只是文本替换,它们没有类型。涉及类型的所有内容都在宏替换之后完成,其行为与您在原始代码中键入替换内容的行为相同。
答案 3 :(得分:2)
编译器永远不会看到宏;预处理器在源文本输入编译器之前扩展所有宏。
所有编译器看到的是
for(int i = 0; i < 40; i++) {...}
并且常量表达式40
的类型是根据2011 C standard的第6.4.4.1节或online C++ standard的第2.13节中的规则确定的。
答案 4 :(得分:1)
在 C 中,宏只是替换文本,这意味着宏表示的文本被复制而不是宏名称,您甚至可以将 C 关键字放在宏中。< / p>
#define [identifier name] [value]
在代码中,标识符名称由值替换。你的定义是:
#define MACRO 40
40
已经是一个int。
所以for(int i = 0; i < 40; i++)
不需要演员表。