C宏是否隐式强制转换?

Are C macros implicitly cast?

本文关键字:转换 是否      更新时间:2023-10-16

我已经搜索了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<操作符的效果。由于i40都是算术类型,因此将执行通常的算术转换,在本例中仍然是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++)不需要强制转换