简体   繁体   English

C宏是否隐式投射?

[英]Are C macros implicitly cast?

I've searched SO, but haven't found an answer to this specific questions. 我搜索了SO,但没有找到这个具体问题的答案。 Forgive me if it's already been answered. 请原谅我已经回答了。

If you have the following: 如果您有以下内容:

#define MACRO  40

You don't assign it to a variable you use it in a loop: 您不将它分配给在循环中使用它的变量:

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

The perprocessor then creates: 然后,每个处理器创建:

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

Would the compiler then implicitly cast it to an int since the comparison is with type int i ? 然后编译器会将它隐式地转换为int,因为比较是使用int i类型吗? I've looked at this question Type of #define variables , and quite a few answers down Edgar Bonet implies that there is an order in which the compiler chooses how to treat the macro? 我看过这个问题#define变量的类型 ,而Edgar Bonet的一些答案暗示了编译器选择如何处理宏的顺序?

This question, How does C++ implicitly cast arguments to a comparator such as <? 这个问题, C ++如何隐式地将参数转换为比较器,如<? , was also suggested, but only describes how implicit casting works with a comparison with two types. ,也有人建议,但只描述了隐式转换如何与两种类型进行比较。 Since a macro doesn't really have a type I'm not sure if this applies. 由于宏实际上没有类型,我不确定这是否适用。

In C and C++, macros are quite literally in-place replacement. 在C和C ++中,宏实际上是就地替换。 The preprocessor will encounter these #define s and replace them as it finds them. 预处理器将遇到这些#define并在找到它们时替换它们。 That's how you can nest macros inside of macros and it only takes 1 pass to preprocess. 这就是你可以在宏中嵌套宏的方法,它只需要1个传递来预处理。

The preprocessor expands macros before the compiler even sees anything. 预处理器在编译器甚至看到任何内容之前扩展宏。 We can see that preprocessing numbers don't have a type by going to the draft C99 standard section 6.4.8 Preprocessing numbers which says: 我们可以看到预处理数字没有类型,可以通过草案C99标准部分6.4.8 预处理数字说:

A preprocessing number does not have type or a value; 预处理号码没有类型或值; it acquires both after a successful conversion (as part of translation phase 7) to a floating constant token or an integer constant token. 它在成功转换(作为转换阶段7的一部分)之后获取浮动常量令牌或整数常量令牌。

The same section in the draft C++ standard is 2.10 . C ++标准草案中的相同部分是2.10

As we can see in C preprocessor Wikipedia article macro expansion happens in phase 4. 正如我们在C预处理器Wikipedia中看到的那样,宏扩展发生在第4阶段。

The conversion of integer constants in C terminology and integer literals in C++ terminology is covered in the draft C99 standard section 6.4.4.1 Integer constants and the following table in paragraph 5 which says: C语言中的整数常量转换和C ++术语中的整数文字在C99标准部分6.4.4.1 整数常量和第5段中的下表中有所说明:

The type of an integer constant is the first of the corresponding list in which its value can be represented 整数常量的类型是相应列表中可以表示其值的第一个

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
---------------------------------------------------------------------------

Table is a modified version of the one from this answer . 表是此答案的修改版本。 The section that covers this in the draft C++ standard is section 2.14.2 which also has a similar table. C ++标准草案中涉及此部分的部分是第2.14.2节,其中也有类似的表。

So in your example 40 has no suffix and is a decimal constant and the first type it can be represented from that section of the table is int . 因此,在您的示例中, 40没有后缀并且是十进制常量,并且可以从表的该部分表示的第一个类型是int

At this point we now end up with the effects of using 40 with the < operator. 此时,我们现在最终得到了使用40<运算符的效果。 Since i and 40 are both arithmetic types then the usual arithmetic conversions will be performed, which in this case will still be int . 由于i40都是算术类型 ,因此将执行通常的算术转换,在这种情况下仍然是int For C99 this is covered in section 6.3.1.8 and C++ section 5 . 对于C99,这将在6.3.1.8和C ++第56.3.1.8介绍。

C macros are simply textual replacements, they have no types. C宏只是文本替换,它们没有类型。 Everything involving types is done after the macro substitution, and acts the same as if you'd typed the replacement in the original code. 涉及类型的所有内容都是宏替换之后完成的其行为与您在原始代码中键入替换内容的行为相同。

The compiler never sees the macro; 编译器永远不会看到宏; the preprocessor expands all macros before the source text is fed into the compiler. 预处理器在源文本输入编译器之前扩展所有宏。

All the compiler sees is 所有编译器都看到了

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

and the type of the constant expression 40 is determined based on the rules in section 6.4.4.1 of the 2011 C standard or section 2.13 of the online C++ standard . 并且,常量表达式40的类型是基于2011 C标准的 6.4.4.1节或在线C ++标准的 2.13节中的规则确定的。

In C macros are just replacement text that means that the text the macro represents is copied instead of the macro name, you can put even C keywords in macro. C宏中只是替换文本,这意味着宏表示的文本被复制而不是宏名称,您甚至可以将C关键字放在宏中。

#define [identifier name] [value]

In the code the identifier name is replace by the value . 在代码中, 标识符名称替换。 Your definition was: 你的定义是:

#define MACRO  40

40 is already an int. 40已经是一个int。 so for(int i = 0; i < 40; i++) no cast is required. 所以for(int i = 0; i < 40; i++)不需要演员表。

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

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