• 宏的二次展开


    原文:点击打开链接

    object-like宏 和 function-like但没有参数的宏,或macro body 有 #(stringified ) or ##(pasted) 的macro, 只执行一遍扫描(simple scan)。否则就要执行两遍扫描。

    两遍扫描:
    prescan: 对参数进行扫描,并对可以展开的参数进行完全的宏展开。
    second scan: 用展开后的参数,对宏体进行展开,对展开后的结果 递归进行 完全的宏展开。


    一遍扫描举例:
    object-like宏:
               #define no_param  hah
               no_param ==> hah

    function-like宏,含有##:

              #define UNAME(a)   a##__LINE__
             UNAME(lidy) ==> lidy__LINE__

    function-like宏,含有#:

             #define INC(x)  x+1
             #define STR(b)  #b   
             STR(INC(x)) ===> "INC(x)"


    递归问题

      无论是simple scan 或 twice scan的宏展开过程,都不允许对同一宏进行第二次展开。

    example:
    simple scan:
         #define x   (4 + y)
         #define y   (2 * x)
       
         x    ==> (4 + y)
              ==> (4 + (2 * x))     这里x不进行二次展开


    twice scan:

        #define a(x)   a(x)+1
        #define b(x)   x+2

        b(a(y)) ==>b(a(y)+1)  先对参数进行扫描
                ==>a(y)+1 +2     a(y)不能 进行第二次展开

    同一宏名不允许重复定义

    如果两个宏定义基本一致,是不会报错的。意思就是说前面定义了某个宏,后面定义同一名字的宏,除非与前面同名的宏定义一致,否则就是重复定义(即把同一个宏名定义为其它的含义),会报错。

    判断宏一致:4条都要满足
    1同是object-or function-like
    2 宏体中的token要相同(就是空白分割的token)
    3 如果有参数,那么形参要相同
    4 有相同的空白处(空白字符数不要求一样)

    相同定义,不是重复定义,不报错
         #define FOUR   (2 + 2)
         #define FOUR         (2    +    2) 
         #define FOUR   (2 /* two */ + 2)

    重复定义错误:
         #define FOUR  (2 + 2)
         #define FOUR  ( 2+2 ) //第4条 空白处不对
         #define FOUR  ( 2 +   2) //第4条 空白处不对
         #define FOUR  (2 * 2) //第3条 宏体的TOKEN不同
         #define FOUR(score,and,seven,years,ago) (2 + 2) //第1条不符号

    宏调用中重定义那个宏,那么新的定义只在参数展开中起作用,外层宏的宏体展开还是使用原先的定义

    #define f(x) x x
         f (1
         #undef f
         #define f 2
         f)
         ==>1 2 1 2
         f(2 3) ==> 2(2 3)//这里的宏体展开怎么会是这样呢?看到这的高手们可以给我解下惑哈!


  • 相关阅读:
    面试题6:用两个栈实现队列
    cygrunsrv: Error starting a service: QueryServiceStatus: Win32 error 1062: 解决办法
    支付系统的对账处理与设计--转
    centos 6.7下安装rabbitmq 3.6.6过程
    Can't access RabbitMQ web management interface after fresh install
    Spring Cloud Netflix Eureka client源码分析
    spring cloud config配置中心源码分析之注解@EnableConfigServer
    量化派基于Hadoop、Spark、Storm的大数据风控架构--转
    Inversion of Control Containers and the Dependency Injection pattern--Martin Fowler
    spark groupByKey 也是可以filter的
  • 原文地址:https://www.cnblogs.com/lulululu/p/3693835.html
Copyright © 2020-2023  润新知