什么类型的宏被考虑?

时间:2016-02-13 01:08:13

标签: c++ macros

如果我将宏定义为#define LOGIC_ONE 1并想在案例陈述中使用LOGIC_ONE,那么LOGIC_ONE会考虑哪种类型?

它是否被识别为int,因为我为值1定义了它?

4 个答案:

答案 0 :(得分:19)

C ++宏是简单的文本替换。

在编译器启动时,预编译器已将LOGIC_ONE替换为1。它就像你现在就写1一样。 (在这种情况下,这是一个int literal ...)

编辑以在评论中包含讨论:
如果您(或有权访问您代码的其他人)将您的#define LOGIC_ONE 1更改为#define LOGIC_ONE "1",则会改变其在您的计划中的行为并成为const char[]字面值。

修改
由于这篇文章比我预期的更受关注,我想我会为那些好奇的人添加对C++ 14 Standard的引用:

  

2.2翻译阶段 [lex.phases]
  (...)
  4.执行预处理指令,扩展宏调用,以及   _Pragma一元运算符表达式被执行。 (...)然后删除所有预处理指令   (...)
  7.分隔标记的空白字符不再重要。每个预处理令牌都转换为令牌。 (2.6)。由此产生的标记在语法和语义上进行分析并翻译为翻译单元。

如上所述,宏在阶段4中被替换,之后不再存在。 “语法和语义”分析发生在第7阶段,代码被编译(“翻译”)。

整数文字在

中指定
  

2.13.2整数文字 [lex.icon]
  (...)
  整数文字是一个没有句点或指数部分的数字序列,可选地分隔单引号,在确定其值时将被忽略。整数文字可以具有指定其基数的前缀和指定其类型的后缀   (...)

     

表5 - 整数文字的类型

   Suffix    |    Decimal literal     | Binary, octal, or hexadecimal literal  
-----------------------------------------------------------------------------
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
                                      | unsigned long long int
-----------------------------------------------------------------------------
Both u or U  |unsigned long long int  | unsigned long long int
and ll or LL |                        |

字符串文字在

中指定
  

2.13.5字符串文字 [lex.string]
  (...)
  1字符串文字是由双引号括起来的字符序列(如2.13.3中所定义),可选地以R,u8,u8R,u,uR,U,UR,L,rLR为前缀,如“...... “,R”(...)“,u8”......“,u8R”**(...)**“,u”......“,uR”*〜(...)*〜“ ,U“......”,UR“zzz(...)zzz”,L“......”或LR“(...)”。   (...)
  6在转换阶段6之后,不以encoding-prefix开头的字符串文字是普通的字符串文字,并使用给定的字符进行初始化。
  7以u8开头的字符串文字,例如u8“asdf”,是UTF-8字符串文字。
  8普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char”数组,其中n是下面定义的字符串的大小,并且   静态存储时间(3.7)。

答案 1 :(得分:11)

预处理器定义没有类型 - 它们基本上只是粘贴"在它们出现的代码中。例如,您在声明中使用它;

int foo = LOGIC_ONE;

然后它将被解释为整数。 (编译器在预处理器之后运行,只将代码视为int foo = 1;)您甚至可以在诸如;

之类的语句中使用它
int foo##LOGIC_ONE;

然后您将创建变量foo1。育!

采用宏定义的另一个例子;

#define LOGIC_ONE hello
int LOGIC_ONE = 5;
printf("%d\n", hello);

这完全有效,并声明一个名为hello的int,但表明没有"类型"对于定义 - hello仅在代码中遇到LOGIC_ONE时被替换。

除非绝对必要,否则请避免使用预处理器宏。专业编码标准通常禁止或严格限制预处理器的使用。通常总是有比使用宏更好的方法。例如,考虑这些替代方案;

static const int LOGIC_ONE = 1;
enum { LOGIC_ONE = 1 };

预处理器是学习者在C中陷入困境的快捷方式。

答案 2 :(得分:8)

LOGIC_ONE在出现的任何地方都被替换为1。就编译器而言,LOGIC_ONE不存在,它只看到1.所以你的问题是'是1是一个int?'。答案是 - >这取决于你输入1

的位置

答案 3 :(得分:6)

宏是文本替换。 1的类型为constexpr int