6.10.3 宏替换

约束

1、两个替换列表是相同的,当且仅当两个替换列表中的预处理符记都具有相同的数、次序、拼写,以及空白分隔符,这里所有的空白分隔符都认为是相同的。

2、当前被定义为一个类似对象的宏的标识符不应该被另一个#define预处理指示符重新定义,除非第二个定义是一个类似对象的宏定义,并且两个替换列表完全相同。类似的,当前被定义为类似函数的宏的标识符不应该用另一个#define预处理指示符重新定义,除非第二个定义是一个类似函数的宏定义,且具有相同个数的形参和拼写,以及两个替换列表完全相同。

3、在一个类似对象的宏定义中,在标识符与替换列表之间应该有空白符。

4、如果宏定义的标识符列表不以省略号结尾,那么在一个类似函数的宏调用中的实参的个数(包括那些由预处理符记组成的实参)应该等于宏定义中的形参个数。否则,在调用中比起宏定义中的形参应该有更多实参(排除...之外)。应该有一个 ) 预处理符记来终结宏调用。

5、标识符__VA_ARGS__应该仅在一个类似函数的宏的替换列表中发生,该宏在形参中使用了省略号。

6、在一个类似函数的宏中的一个形参标识符应该在其作用域中是唯一声明的。

语义

7、立即跟在define后面的标识符被称为宏名。对于宏名有一个名字空间。任一在预处理符记之前或之后的空白字符不被认为是替换列表中的一部分。

8、如果一个 # 预处理符记,后面跟着一个标识符,在词法上发生在一个预处理指示符可能开始的位置,那么该标识符并不受宏替换的影响。

9、以下形式的一个预处理指示符

# define    identifier    replacement-list    new-line

定义了一个类似对象的宏,使得该宏名[注:由于到宏替换时刻为止,所有字符常量与字符串字面量都是预处理符记,而不是可能包含类似于标识符的子序列的序列(见5.1.1.2,翻译阶段),它们对于宏名或形参都永远不会被扫描。]每个后续的实例用由剩余的指示符所构成的预处理符记的替换列表来代替。替换列表然后对更多宏名重新扫描,正如以下所说明的。

10、以下形式的一个预处理指示符

#  define  identifier  lparen  identifier-listopt  )  replacement-list  new-line

#  define  identifier  lparen ...  )  replacement-list  new-line

#  define  identifier  lparen  identifier-list  ,  ... )  replacement-list  new-line

定义了一个带有形参的类似函数的宏,其用法在语法上跟一个函数调用很类似。宏的形参由可选的标识符列表所指定,这些标识符的作用域从它们在标识符列表中的声明开始一直延伸到终结#define预处理指示符的换行字符。类似函数的宏的每个后续的实例,后面跟着一个 ( 作为下一个预处理符记,引出预处理符记序列,该序列被宏定义中的替换列表来取代(在该宏被调用时)。被取代的预处理符记序列由匹配的 ) 预处理符记来终结,跳过中间出现的左右圆括号对预处理符记。在预处理符记序列内组成一个类似函数的宏的调用,换行就被认为是一个正常的空白字符。

11、由最外层皮配圆括号所绑定的预处理符记序列,为类似函数的宏形成了实参列表。在列表内的每个实参用逗号预处理符记分隔,但在匹配内部圆括号之间的逗号预处理符记并不分隔实参。如果在实参列表内有预处理符记序列,这些实参将作为预处理符记指示符[注:不管该名,一个非指示符是一个预处理符记],那么行为是未定义的。

12、在宏定义中的标识符列表中有一个 ... ,那么尾随实参,包括任一用于分割的逗号预处理符记,被融合,形成一单个项:可变实参。如此结合的实参个数是这么来的,跟在融合之后的,实参个数比宏定义中形参个数多1(不包括 ...)。

6.10.3.1 实参替换

1、在一个类似函数的宏调用的实参被识别之后,实参替换发生。在替换列表中的一个形参,除非前面添有一个###预处理符,或者后面跟着一个##预处理符记(见下面),否则就在所有包含其中的宏展开之后,就被相应的实参替换。在被替换之前,每个实参的预处理符记完全被宏替换,就好比它们形成了剩余预处理器文件;没有其它预处理符记可用。

ISO/IEC 9899:2011 条款6.10.3——宏替换的更多相关文章

  1. ISO/IEC 9899:2011 条款6.10——预处理指示符

    6.10 预处理指示符 语法 1.preprocessing-file: groupopt group: group-part group    group-part group-part: if-s ...

  2. ISO/IEC 9899:2011 条款6.10.2——源文件包含

    6.10.2 源文件包含 约束 1.一个#include指示符应该指定一个能被实现处理的头文件或源文件. 语义 2.一个预处理指示符如下形式 #    include    <h-char-se ...

  3. ISO/IEC 9899:2011 条款6.10.1——条件包含

    6.10.1 条件包含 约束 1.控制条件包含的表达式应该是一个整数常量表达式,除了:标识符(包括那些词法上与关键字相同的)被解析为以下所描述的:[注:因为控制常量表达式在翻译阶段4期间被计算,所以所 ...

  4. ISO/IEC 9899:2011 条款3——术语、定义与符号

    3. 术语.定义与符号 1.对于此国际标准的意图,应用了以下定义.其它术语是在用斜体类型或一个语法规则左侧出现的地方定义.在本国际标准中所显式定义的术语不被假定为对其它地方所定义的类似术语的隐式引用. ...

  5. ISO/IEC 9899:2011 条款5——5.2.1 字符集

    5.2.1 字符集 1.两个字符集和它们相关联的依次顺序应该被定义:写在源文件中的集合(源字符集),以及在执行环境中被解释的集合(执行字符集).每个集合此外被划分为一个基本字符集,其内容由本子条款给出 ...

  6. ISO/IEC 9899:2011 条款6.4.2——标识符

    6.4.2 标识符 6.4.2.1 通用 语法 1.identifier: identifier-nodigit identifier    identifier-nondigit identifie ...

  7. ISO/IEC 9899:2011 条款6.4.3——通用字符名

    6.4.3 通用字符名 语法 1.通用字符名: universal_character-name: \u hex-quad(四位十六进制数) \U hex-quad hex-quad hex-quad ...

  8. ISO/IEC 9899:2011 条款6.7.10——静态断言

    6.7.10 静态断言 语法 1.static-assert_declaration: _Static_assert    (    constant-expression    ,    strin ...

  9. ISO/IEC 9899:2011 条款6.5.10——按位与操作符

    6.5.10 按位与操作符 语法 1.AND-expression: equality-expression AND-expression    equality-expression 约束 2.这些 ...

随机推荐

  1. C#-使用GoogleAPI读写spreadsheets

    https://docs.google.com/spreadsheets/在线使用一些常用办公工具,比如excel. 如需要C#代码自动读写这些excel,则需要使用GoogleAPI. 封装的公用类 ...

  2. Python入门篇-函数、参数及参数解构

    Python入门篇-函数.参数及参数解构 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数概述 1>.函数的作用即分类 函数 数学定义:y=f(x) ,y是x的函数,x ...

  3. Java 返回字符串中第一个不重复字符的下标 下标从0开始

    比如abcdefgabdef 其中字符c和g不重复,返回c的小标,下标从0开始,那么是2 package com.example.demo; import org.testng.annotations ...

  4. dockerhub下载加速

    curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f5dad4ec.m.daocloud.io syste ...

  5. Jupyter Notebook(持续更新)

    1.引用Pandas import pandas as pd 2.创建DataFrame bb=pd.DataFrame(enron_data) 3.查看列 & 行 dataFrame.sha ...

  6. 《团队作业第三、四周》五阿哥小组Scrum 冲刺阶段---Day2

    <团队作业第三.四周>五阿哥小组Scrum 冲刺阶段---Day2 一.项目燃尽图 二.项目进展 20182310周烔今日进展: 主要任务一览:完成总博客的提交,制定接下来的计划,编写博客 ...

  7. fiddler抓取手机https请求详解

    前言: Fiddler是在 windows下常用的网络封包截取工具,在做移动开发时,我们为了调试与服务器端的网络通讯协议,常常需要截取网络封包来分析,fiddler默认只能抓取http请求,需要配置和 ...

  8. STM32 IAP程序 源码 和测试代码 有详细的中文注释

    http://bbs.21ic.com/forum.php?mod=viewthread&tid=588265&reltid=624002&pre_pos=2&ext= ...

  9. keras中to_categorical()函数解析

    from keras.utils.np_utils import * # 类别向量定义 b = [0, 1, 2, 3, 4, 5, 6, 7, 8] # 调用to_categorical将b按照9个 ...

  10. tensorflow2.0 学习(二)

    线性回归问题 # encoding: utf-8 import numpy as np import matplotlib.pyplot as plt data = [] for i in range ...