C 宏是隐式转换的吗? [英] Are C macros implicitly cast?

查看:30
本文介绍了C 宏是隐式转换的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经搜索过 SO,但没有找到这个特定问题的答案.如果已经回答,请见谅.

如果您有以下情况:

#define MACRO 40

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

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

然后,perprocessor 创建:

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

由于比较是与类型 int i 进行比较,因此编译器是否会将其隐式转换为 int?我已经看过这个问题Type of #define variables,并且在 Edgar 下有不少答案Bonet 暗示编译器选择如何处理宏有一个顺序?

这个问题,C++如何隐式还建议将参数转换为比较器,例如 <?,但仅描述了隐式转换如何与两种类型的比较一起工作.由于宏实际上没有类型,我不确定这是否适用.

解决方案

预处理器扩展在编译器甚至看到任何东西之前的宏.我们可以通过转到 c99 标准草案 部分 6.4.8 预处理数字 说:

<块引用>

预处理数字没有类型或值;它同时获得在成功转换(作为翻译阶段 7 的一部分)后浮动常量令牌或整数常量令牌.

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

正如我们在 C 预处理器维基百科文章中看到的那样,宏扩展发生在第 4 阶段.

C 术语中的整数常量和 C++ 术语中的整数文字的转换在草案 C99 标准部分 6.4.4.1 整数常量 和段落中的下表中进行了介绍5 上面写着:

<块引用>

整数常量的类型是对应列表的第一个其价值体现在哪里

<上一页>八进制或十六进制后缀 十进制常数 常数---------------------------------------------------------------------------无 int intlong int 无符号整数long long int long int无符号长整数长长整数unsigned long long int---------------------------------------------------------------------------u 或 U unsigned int unsigned int无符号长整数 无符号长整数unsigned long long int unsigned long long int---------------------------------------------------------------------------l 或 L long int long intlong long int 无符号 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 intunsigend 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++ 部分 5 中有介绍.

I've searched SO, but haven't found an answer to this specific questions. 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? 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?

This question, How does C++ implicitly cast arguments to a comparator such as <?, 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.

解决方案

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:

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.

The same section in the draft C++ standard is 2.10.

As we can see in C preprocessor Wikipedia article macro expansion happens in phase 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:

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.

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.

At this point we now end up with the effects of using 40 with the < operator. Since i and 40 are both arithmetic types then the usual arithmetic conversions will be performed, which in this case will still be int. For C99 this is covered in section 6.3.1.8 and C++ section 5.

这篇关于C 宏是隐式转换的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆