C宏是否隐式投射?

时间:2014-06-10 17:16:46

标签: c++ c macros types c-preprocessor

我搜索了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 <?,但仅描述了隐式转换如何与两种类型进行比较。由于宏实际上没有类型,我不确定这是否适用。

5 个答案:

答案 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<运算符结合使用。由于i40都是算术类型,因此将执行通常的算术转换,在这种情况下仍将是 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++)不需要演员表。