指定为#define值的内存类型是什么?

时间:2013-09-29 18:53:04

标签: c++ c c-preprocessor

考虑以下代码,使用各种#define语句;

 #define PUSH 0x50
 #define POP  0x58
 #define NOP  0x90
 #define JUNK __asm__(PUSH, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, POP)
 #define J 0.752
 #define L 27

前几个状态定义了一些HEX值,它们是汇编指令,然后是一组。

倒数第二行定义了一个名为J的浮点数。

final语句定义了一个名为L的整数。

这些内存定义是“无类型的”,因为它们是常量吗?我猜不是因为我无法想象它会如何起作用。编译器是否自动分配最大的relivant类型,例如float或int?

3 个答案:

答案 0 :(得分:4)

这些不是“内存定义”。它们是预处理器宏。编译器本身没有它们的可见性,因为它们在运行之前都被替换(主要是通过复制和粘贴)。

答案 1 :(得分:2)

在调用编译器本地之前,您的宏将被字面序列替换(替换)它们所定义的字符序列。即你的宏甚至不是“十六进制值”。它们代表着没有语言级语义含义的字符序列。

替换后,编译器将正确看到这些字符序列,并根据周围的上下文进行相应的解释。在“典型”情况下,编译器将它们解释为整数常量。整数常量是C中的 rvalues ,它们没有与之关联的内存。从概念上讲,它们并不存在于记忆中。但这并不能使他们无类型。在C中,常量的格式定义了它的类型。 0.752double类型的常量,而27int类型的常量。

但同样,替代序列的语义含义可能(并且将会)取决于它所处的上下文。如果您愿意,可以将这些宏“实例化”为字符串文字,或者将它们与其他字符序列连接起来,从而完全改变它们的含义。

答案 2 :(得分:2)

具有#前缀的所有这些语句(例如#define#include和许多其他语句都不是编译器看到的真正的C / C ++语句。这些是所谓的预处理程序指令。

预处理器是一个软件,它在编译器处理之前遍历所有代码文件。预处理器在文件中搜索特殊命令 - 称为预处理程序指令。一旦找到指令,预处理器就会对代码文件执行一些操作。编译器只能编译原始代码文件上的预处理结果。

例如,当预处理器遇到#include指令时,它只是将#include "whatever.h"替换为文件whatever.h的内容。只有在预处理器完成之后,编译器才能处理生成的文件 - 其中whatever.h的内容已经替换为#include

#define只是另一个预处理程序指令,用于将某些文本替换为另一段文本。

#define PUSH 0x50

告诉预处理器用PUSH替换文件中找到的语句中的0x500x50没有类型,它不是整数或常量或任何东西,只是粘贴到原始代码文件中的一段文本,在将文本PUSH传递给编译器之前替换它。

编译器处理后,0x50文本将根据其语法上下文进行编译。