C宏是否隐式强制转换?
Are C macros implicitly cast?
我已经搜索了SO,但还没有找到这个特定问题的答案。如果已经有人回答了,请原谅我。
如果您有以下内容:
#define MACRO 40
你不把它赋值给一个变量,你在循环中使用它:
for(int i = 0; i < MACRO; i++) {...
然后超处理器创建:
for(int i = 0; i < 40; i++) {...
编译器会隐式地将其强制转换为int类型,因为比较类型是int i
吗?我研究了#define变量的类型这个问题,Edgar Bonet的很多答案暗示编译器选择如何处理宏是有顺序的。
这个问题,c++如何隐式地将参数强制转换为<之类的比较器?,但只描述了隐式强制转换如何与两个类型进行比较。由于宏没有真正的类型,我不确定这是否适用。>
在C和c++中,宏实际上是就地替换的。预处理器将遇到这些#define
,并在找到它们时替换它们。这就是如何在宏中嵌套宏,并且只需要1次预处理。
预处理器在编译器看到任何内容之前展开宏。我们可以看到预处理数字没有类型,参见C99标准草案6.4.8
预处理数字,其中说:
预处理数没有类型或值;两者都得到了在成功转换(作为翻译阶段7的一部分)到浮点常量令牌或整型常量令牌。
c++标准草案中的同一章节是2.10
。
正如我们在C预处理器中看到的,维基百科文章中的宏扩展发生在阶段4。
C术语中的整型常量和c++术语中的整型常量的转换在C99标准草案6.4.4.1
章节中有介绍,整型常量和下表在5段落中说:
<>之前八进制或十六进制后缀十进制常数---------------------------------------------------------------------------无int int长整型无符号整型Long Long int Long int无符号长整型长长intUnsigned long long int---------------------------------------------------------------------------u或者u unsigned intUnsigned long intUnsigned long long int---------------------------------------------------------------------------l或l long int long intLong Long int unsigned Long int长长intUnsigned long long int---------------------------------------------------------------------------u和u unsigned long int都可以和l或l unsigned long int unsigned long int---------------------------------------------------------------------------all或ll long long int long long intunsigned long long int---------------------------------------------------------------------------u或u unsigned long long int unsigned long long intand all or ll---------------------------------------------------------------------------之前整型常量的类型是对应列表的第一个其中它的值可以表示为
Table是这个答案的修改版本。在c++标准草案中,讨论这个问题的章节是2.14.2
,它也有一个类似的表。
所以在你的例子中,40
没有后缀,是一个十进制常量,它可以从表的那一部分表示的第一个类型是int。
40
和<
操作符的效果。由于i
和40
都是算术类型,因此将执行通常的算术转换,在本例中仍然是int。对于C99,这将在6.3.1.8
节和c++ 5节中介绍。
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++)
不需要强制转换
- 是否可以从int转换为enum类类型
- 隐式转换是否应该在模板参数的上下文中工作?
- C++ stod:字符串到浮点转换是否一致
- 自动(toCast)显式转换是否计划在未来C++标准?
- 类类型的左值到右值转换:是否涉及复制?
- 矢量之间的转换是否定义了行为
- 如何检测 W2A 转换是否完全成功
- interpret_cast和c样式强制转换是否兼容(按照c++标准)
- 仅更改常量性的指针强制转换是否可以调用未定义的行为
- C++ 强制转换是否会创建新对象
- 在类树中使用动态强制转换是否可以接受
- 在C++中的函数调用内部执行强制转换时,强制转换是否真的有效
- 检查显式强制转换是否成功
- 如果派生类只包含方法(没有成员变量),向下强制转换是否安全?
- 使用这种智能指针强制转换是否安全?
- 类型转换是否消耗额外的CPU周期?
- 在void*和void*之间进行强制转换时,混合使用静态强制转换和重新解释强制转换是否不安全?
- 类型转换是否在内部使用条件?(C / c++, c#)
- 如何检测转换是否在 c++0x 中失败
- 如何在CRTP中实现向下转换是否有效的编译时检查