C的宏,读不太懂,求教

Binary2Hex 2013-07-04 10:49:26
一段C代码,其中的宏,不太懂在这里怎么展开啊...


enum md_opcode {
OP_NA = 0,
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) OP,
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT) OP,
#define CONNECT(OP)
#include "machine.def"
OP_MAX
};


这里枚举类型的第二行至第四行应该怎么理解...?

include的machine.def中,关于DEFINST,DEFLINK,以及CONNECT都有存在,是直接替换吗?(貌似说明的有点绕口)

譬如说machine.def中有很多类似类似于这样的存在,这是其中一个DEFINST的形式,它拥有和枚举类型定义中一致的格式

DEFINST(LDA, 0x08,
"lda", "a,o(b)",
IntALU, F_ICOMP,
DGPR(RA), DNA, DNA, DGPR(RB), DNA)

是否可以这样理解:
第一段代码(枚举的定义部分)的第二行不只是定义了一个DEFINST,而是定义了一类DEFINST,它们拥有统一的格式,而对应的具体实例就是上面一段引自于machine.def中的代码,然后上例中的LDA就作为OP,成为枚举类型的一个成员而存在。这样在machine.def中所有存在与定义格式一致的DEFINST的OP字段因为include的缘故,全部成为枚举类型的成员。

同理,DEFLINK和CONNECT也是一样的实现。是否可以这样理解?

说这么多不知道听众有没有理解,毕竟是一段完全没有上下文的代码...
然后我发帖的时候完全想不明白,敲的过程中有了上面的理解,不知到理解的对不对...

最后的
#define CONNECT(OP)
这种格式也可以吗?(不是传统意义上的
#define A B
)

C的宏好难读啊...
...全文
268 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2013-07-05
  • 打赏
  • 举报
回复
展开过程其实只有一个规则, 就是替换, 注意后面的续行符 \ , 有这个表明仍然是宏定义的范围, 宏定义还没结束. 有了这一段的定义后,

#define DEFINST(OP,MSK,NAME,OPFORM,RES,CLASS,O1,O2,I1,I2,I3)    \
    case OP:                            \
      /* execute the instruction */                \
      SYMCAT(OP,_IMPL);                        \
      fprintf(stderr, "pc = %llX\n", regs.regs_PC); \
      break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)                \
    case OP:                            \
      panic("attempted to execute a linking opcode");
#define CONNECT(OP)    /* nada... */
#define DECLARE_FAULT(FAULT)                    \
      {                                \
    fault = (FAULT);                    \
    break;                            \
      }
#include "machine.def" 的时候 machine.def 中的内容将按照上面的来展开了. 比如里面的 DEFINST(LDA, 0x08, "lda", "a,o(b)", IntALU, F_ICOMP, DGPR(RA), DNA, DNA, DGPR(RB), DNA) 会被展开成: case LDA: /* execute the instruction */ SYMCAT(LDA,_IMPL); fprintf(stderr, "pc = %llX\n", regs.regs_PC); break;
Binary2Hex 2013-07-05
  • 打赏
  • 举报
回复
引用 2 楼 adlay 的回复:
你的理解应该是对的. 虽然表述起来有点乱. #define CONNECT(OP) 是把后面的 CONNECT(xxxx) 替换成空的, 相当于删除不使用一样. 和 #define A B 不是一个意思.
这段是看得有点明白了,但是后面又有不懂的地方想要请教了...

switch (ent->op) {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,CLASS,O1,O2,I1,I2,I3)	\
    case OP:							\
      /* execute the instruction */				\
      SYMCAT(OP,_IMPL);						\
      fprintf(stderr, "pc = %llX\n", regs.regs_PC); \
      break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)				\
    case OP:							\
      panic("attempted to execute a linking opcode");
#define CONNECT(OP)	/* nada... */
#define DECLARE_FAULT(FAULT)					\
      {								\
	fault = (FAULT);					\
	break;							\
      }
#include "machine.def"
    default:
      fault = md_fault_unimpl;
    }
  }
这段是跟之前的有一定关联的代码,swith的ent->op类型就是一楼的枚举类型。然后这里面的case分支我就看不懂了... 能解释一下宏展开的过程吗...?
ForestDB 2013-07-05
  • 打赏
  • 举报
回复
顶LS的,直接看预处理后的结果,就明白了预处理做了什么。
赵4老师 2013-07-05
  • 打赏
  • 举报
回复
编译选项加/EP /P,重新编译,查看宏展开后对应的.i文件。gcc加-E
Binary2Hex 2013-07-04
  • 打赏
  • 举报
回复
引用 1 楼 bluewanderer 的回复:
这种东西术语叫meta-programming #include "machine.def"会因为那几个宏的定义不同产生不同的代码。 这里machine.def相当于把每条指令的相关信息都提供了,通过用不同方式定义宏之后再包含machine.def就可以提取出不同的信息。
这段是看得有点明白了,但是后面又有不懂的地方想要请教了...

switch (ent->op) {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,CLASS,O1,O2,I1,I2,I3)	\
    case OP:							\
      /* execute the instruction */				\
      SYMCAT(OP,_IMPL);						\
      fprintf(stderr, "pc = %llX\n", regs.regs_PC); \
      break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)				\
    case OP:							\
      panic("attempted to execute a linking opcode");
#define CONNECT(OP)	/* nada... */
#define DECLARE_FAULT(FAULT)					\
      {								\
	fault = (FAULT);					\
	break;							\
      }
#include "machine.def"
    default:
      fault = md_fault_unimpl;
    }
  }
这段是跟之前的有一定关联的代码,swith的ent->op类型就是一楼的枚举类型。然后这里面的case分支我就看不懂了... 能解释一下宏展开的过程吗...?
www_adintr_com 2013-07-04
  • 打赏
  • 举报
回复
你的理解应该是对的. 虽然表述起来有点乱. #define CONNECT(OP) 是把后面的 CONNECT(xxxx) 替换成空的, 相当于删除不使用一样. 和 #define A B 不是一个意思.
bluewanderer 2013-07-04
  • 打赏
  • 举报
回复
这种东西术语叫meta-programming #include "machine.def"会因为那几个宏的定义不同产生不同的代码。 这里machine.def相当于把每条指令的相关信息都提供了,通过用不同方式定义宏之后再包含machine.def就可以提取出不同的信息。

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧