宏定义函数求解

lk0098 2014-07-31 10:53:33
最近读一个开源项目quagga,看到其中有这样一个内容:
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
DEFUN_CMD_FUNC_TEXT(funcname)


然后对应的几个宏:
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
struct cmd_element cmdname = \
{ \
.string = cmdstr, \
.func = funcname, \
.doc = helpstr, \
.attr = attrs, \
.daemon = dnum, \
};

#define DEFUN_CMD_FUNC_DECL(funcname) \
static int funcname (struct cmd_element *, struct vty *, int, const char *[]);

#define DEFUN_CMD_FUNC_TEXT(funcname) \
static int funcname \
(struct cmd_element *self __attribute__ ((unused)), \
struct vty *vty __attribute__ ((unused)), \
int argc __attribute__ ((unused)), \
const char *argv[] __attribute__ ((unused)) )


然后有几个问题:
1.上述有几个宏里面的 static int funcname,都没有内容实现,我在源码中找好久都没找到,但是却见到有使用这些函数,请问这是怎么实现的。
2.在DEFUN_CMD_FUNC_TEXT、DEFUN_CMD_FUNC_DECL都以相同的名字作为函数名,不会造成重名吗?C里面没有重载的啊
求解,谢谢!
...全文
249 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
lk0098 2014-08-14
  • 打赏
  • 举报
回复
 
static int gateway_ecdysis (struct cmd_element *, int, const char *[]); 
struct cmd_element gateway_ecdysis_cmd = { .string = "gateway ecdysis", .func = gateway_ecdysis, .doc = "Enable a gateway translation protocol process\n", }; 
static int gateway_ecdysis (struct cmd_element *self , int argc , const char *argv[] )
{
  return 1;
}
擦,展开来看了半天才发现一个是声明一个是实现啊。 谢谢了!
wanght99 2014-08-02
  • 打赏
  • 举报
回复
引用 6 楼 lk0098 的回复:
[quote=引用 3 楼 wanght99 的回复:] 这里的宏是带参数的 #define DEFUN_CMD_FUNC_DECL(func1) 会声明一个func1, #define DEFUN_CMD_FUNC_DECL(func2)会声明一个func2, 互相不影响
两个函数不是同名吗,这样没有影响?[/quote] 两个不是同名的, 函数名取决于使用宏的时候传给它的名字, 我上面的例子里一个是func1, 一个是func2, 可以理解为一种参数传递
勤奋的小游侠 2014-08-01
  • 打赏
  • 举报
回复
引用 8 楼 lk0098 的回复:
[quote=引用 7 楼 brookmill 的回复:] 举个例子吧:
DEFUN(func_name1, cmd_name1, cmd_str1, help_str1)
{
  return 1;
}

DEFUN(func_name2, cmd_name2, cmd_str2, help_str2)
{
  return 2;
}
这两个宏展开之后变成这样:
static int func_name1 (struct cmd_element *, struct vty *, int, const char *[]);
struct cmd_element cmd_name1 = { .string = cmd_str1, .func = func_name1, .doc = help_str1, .attr = 0, .daemon = 0, };
static int func_name1 (struct cmd_element *self __attribute__ ((unused)), struct vty *vty __attribute__ ((unused)), int argc __attribute__ ((unused)), const char *argv[] __attribute__ ((unused)) )
{
  return 1;
}

static int func_name2 (struct cmd_element *, struct vty *, int, const char *[]);
struct cmd_element cmd_name2 = { .string = cmd_str2, .func = func_name2, .doc = help_str2, .attr = 0, .daemon = 0, };
static int func_name2 (struct cmd_element *self __attribute__ ((unused)), struct vty *vty __attribute__ ((unused)), int argc __attribute__ ((unused)), const char *argv[] __attribute__ ((unused)) )
{
  return 2;
}
谢谢你的回答。应该是这样:首先执行的宏:
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
  DEFUN_CMD_FUNC_DECL(funcname) \
  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
  DEFUN_CMD_FUNC_TEXT(funcname)
然后它包括三个宏,其中DEFUN_CMD_FUNC_DECL是:
#define DEFUN_CMD_FUNC_DECL(funcname) \
  static int funcname (struct cmd_element *, struct vty *, int, const char *[]);
而DEFUN_CMD_FUNC_TEXT是:
#define DEFUN_CMD_FUNC_TEXT(funcname) \
  static int funcname \
    (struct cmd_element *self __attribute__ ((unused)), \
     struct vty *vty __attribute__ ((unused)), \
     int argc __attribute__ ((unused)), \
     const char *argv[] __attribute__ ((unused)) )
二者都是用DEFUN宏中的funcname参数实现定义函数名的,那么就应是两个函数名一样啊,为什么不是重定义呢 我明白你的意思是如果使用不同宏的时候不会重名,但是如果一个宏呢,不是会重名吗? 是不是因为__attribute__ ((unused))的关系,这个是什么东西呢?[/quote] DEFUN_CMD_FUNC_TEXT这个宏使用的地方后面肯定跟有花括号的查找看看。 要不你像楼主说的编译个中间文件出来看一下宏展开后的中间代码就什么都明白了
brookmill 2014-08-01
  • 打赏
  • 举报
回复
举个例子吧:
DEFUN(func_name1, cmd_name1, cmd_str1, help_str1)
{
  return 1;
}

DEFUN(func_name2, cmd_name2, cmd_str2, help_str2)
{
  return 2;
}
这两个宏展开之后变成这样:
static int func_name1 (struct cmd_element *, struct vty *, int, const char *[]);
struct cmd_element cmd_name1 = { .string = cmd_str1, .func = func_name1, .doc = help_str1, .attr = 0, .daemon = 0, };
static int func_name1 (struct cmd_element *self __attribute__ ((unused)), struct vty *vty __attribute__ ((unused)), int argc __attribute__ ((unused)), const char *argv[] __attribute__ ((unused)) )
{
  return 1;
}

static int func_name2 (struct cmd_element *, struct vty *, int, const char *[]);
struct cmd_element cmd_name2 = { .string = cmd_str2, .func = func_name2, .doc = help_str2, .attr = 0, .daemon = 0, };
static int func_name2 (struct cmd_element *self __attribute__ ((unused)), struct vty *vty __attribute__ ((unused)), int argc __attribute__ ((unused)), const char *argv[] __attribute__ ((unused)) )
{
  return 2;
}
lk0098 2014-08-01
  • 打赏
  • 举报
回复
引用 3 楼 wanght99 的回复:
这里的宏是带参数的 #define DEFUN_CMD_FUNC_DECL(func1) 会声明一个func1, #define DEFUN_CMD_FUNC_DECL(func2)会声明一个func2, 互相不影响
两个函数不是同名吗,这样没有影响?
lk0098 2014-08-01
  • 打赏
  • 举报
回复
引用 2 楼 brookmill 的回复:
比较一下DEFUN_CMD_FUNC_TEXT 和 DEFUN_CMD_FUNC_DECL 就会发现除了 __attribute__ 之外,返回值和参数列表都是一样的。 DEFUN_CMD_FUNC_DECL后面有分号,所以是声明(DECLare) DEFUN_CMD_FUNC_TEXT后面没有分号,所以紧接着下面一定是有函数体{ ... }
还真没有实现.....他整个结构如下:
/* helper defines for end-user DEFUN* macros */
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
  struct cmd_element cmdname = \
  { \
    .string = cmdstr, \
    .func = funcname, \
    .doc = helpstr, \
    .attr = attrs, \
    .daemon = dnum, \
  };

#define DEFUN_CMD_FUNC_DECL(funcname) \
  static int funcname (struct cmd_element *, struct vty *, int, const char *[]);

#define DEFUN_CMD_FUNC_TEXT(funcname) \
  static int funcname \
    (struct cmd_element *self __attribute__ ((unused)), \
     struct vty *vty __attribute__ ((unused)), \
     int argc __attribute__ ((unused)), \
     const char *argv[] __attribute__ ((unused)) )

/* DEFUN for vty command interafce. Little bit hacky ;-). */
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
  DEFUN_CMD_FUNC_DECL(funcname) \
  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
  DEFUN_CMD_FUNC_TEXT(funcname)
宏后面不一定要跟分号的吧
lk0098 2014-08-01
  • 打赏
  • 举报
回复
引用 1 楼 brookmill 的回复:
DEFUN_CMD_FUNC_TEXT 就是实现 DEFUN_CMD_FUNC_DECL 就是声明
两个都是声明啊,都是一堆参数,哪里有运算实现啊?求解,谢谢
wanght99 2014-08-01
  • 打赏
  • 举报
回复
这里的宏是带参数的 #define DEFUN_CMD_FUNC_DECL(func1) 会声明一个func1, #define DEFUN_CMD_FUNC_DECL(func2)会声明一个func2, 互相不影响
707wk 2014-08-01
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
编译选项加/EP /P,重新编译,查看宏展开后对应的.i文件。gcc加-E
+1
  • 打赏
  • 举报
回复
引用 3 楼 wanght99 的回复:
这里的宏是带参数的 #define DEFUN_CMD_FUNC_DECL(func1) 会声明一个func1, #define DEFUN_CMD_FUNC_DECL(func2)会声明一个func2, 互相不影响
++
赵4老师 2014-08-01
  • 打赏
  • 举报
回复
编译选项加/EP /P,重新编译,查看宏展开后对应的.i文件。gcc加-E
lk0098 2014-08-01
  • 打赏
  • 举报
回复
引用 7 楼 brookmill 的回复:
举个例子吧:
DEFUN(func_name1, cmd_name1, cmd_str1, help_str1)
{
  return 1;
}

DEFUN(func_name2, cmd_name2, cmd_str2, help_str2)
{
  return 2;
}
这两个宏展开之后变成这样:
static int func_name1 (struct cmd_element *, struct vty *, int, const char *[]);
struct cmd_element cmd_name1 = { .string = cmd_str1, .func = func_name1, .doc = help_str1, .attr = 0, .daemon = 0, };
static int func_name1 (struct cmd_element *self __attribute__ ((unused)), struct vty *vty __attribute__ ((unused)), int argc __attribute__ ((unused)), const char *argv[] __attribute__ ((unused)) )
{
  return 1;
}

static int func_name2 (struct cmd_element *, struct vty *, int, const char *[]);
struct cmd_element cmd_name2 = { .string = cmd_str2, .func = func_name2, .doc = help_str2, .attr = 0, .daemon = 0, };
static int func_name2 (struct cmd_element *self __attribute__ ((unused)), struct vty *vty __attribute__ ((unused)), int argc __attribute__ ((unused)), const char *argv[] __attribute__ ((unused)) )
{
  return 2;
}
谢谢你的回答。应该是这样:首先执行的宏:
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
  DEFUN_CMD_FUNC_DECL(funcname) \
  DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
  DEFUN_CMD_FUNC_TEXT(funcname)
然后它包括三个宏,其中DEFUN_CMD_FUNC_DECL是:
#define DEFUN_CMD_FUNC_DECL(funcname) \
  static int funcname (struct cmd_element *, struct vty *, int, const char *[]);
而DEFUN_CMD_FUNC_TEXT是:
#define DEFUN_CMD_FUNC_TEXT(funcname) \
  static int funcname \
    (struct cmd_element *self __attribute__ ((unused)), \
     struct vty *vty __attribute__ ((unused)), \
     int argc __attribute__ ((unused)), \
     const char *argv[] __attribute__ ((unused)) )
二者都是用DEFUN宏中的funcname参数实现定义函数名的,那么就应是两个函数名一样啊,为什么不是重定义呢 我明白你的意思是如果使用不同宏的时候不会重名,但是如果一个宏呢,不是会重名吗? 是不是因为__attribute__ ((unused))的关系,这个是什么东西呢?
brookmill 2014-07-31
  • 打赏
  • 举报
回复
比较一下DEFUN_CMD_FUNC_TEXT 和 DEFUN_CMD_FUNC_DECL 就会发现除了 __attribute__ 之外,返回值和参数列表都是一样的。 DEFUN_CMD_FUNC_DECL后面有分号,所以是声明(DECLare) DEFUN_CMD_FUNC_TEXT后面没有分号,所以紧接着下面一定是有函数体{ ... }
brookmill 2014-07-31
  • 打赏
  • 举报
回复
DEFUN_CMD_FUNC_TEXT 就是实现 DEFUN_CMD_FUNC_DECL 就是声明
1.数字排列 2.奖金分配问题 3.已知条件求解整数 4.输入日期判断第几天 5.输入整数进行排序 6.用*号显示字母C的图案 7.显示特殊图案 8.打印九九口诀 9.输出国际象棋棋盘 10.打印楼梯并按条件打印笑脸 11.经典兔子问题 12.判断素数 13.水仙花数问题 14.正整数分解质因数 15.学习成绩划分 16.正整数求其最大公约数和最小公倍数 17.统计英文字母/空格/数字个数 18.求s=a+aa+aaa+aa...a的值 19.求解"完数" 20.球体自由落下物理问题 21.猴子吃桃问题 22.乒乓球比赛抽签问题 23.打印菱形图案 24.分数数列求和 25.求1+2!+3!+...+20!的和 26.利用递归方法求5! 27.将输入字符以相反顺序打印 28.岁数问题 29.求解正整数位数 30.判断回文数 31.星期几猜测游戏 32.改变文本颜色 33.学习gotoxy()与clrscr()函数 34.练习函数调用 35.设置文本颜色 36.求100之内的素数 37.对10个数进行排序 38.求3*3矩阵对角线元素之和 39.数字插入数组重新排序 40.将一个数组逆序输出 41.static定义静态变量用法 42.使用auto定义变量用法 43.使用static的另一用法 44.使用external的用法 45.使用register定义变量方法 46.#define命令练习(1) 47.#define命令练习(2) 48.#define命令练习(3) 49.#if #ifdef和#ifndef的综合应用 50.#include 的应用练习 51.学习使用按位与 & 52.学习使用按位或 | 53.学习使用按位异或 ^ 54.取一个整数从右端开始的4~7位。 55.学习使用按位取反~ 56.用circle画圆形 57.学用line画直线 58.用rectangle画方形 59.画图综合例子 60.画图综合例子2 61.打印杨辉三角形 62.学习putpixel画点 63.画椭圆ellipse 64.利用ellipse and rectangle画图 65.画个最优美的图案 66.输入3个数字按大小顺序输出 67.输入数组交换元素重新输出 68.多个整数后移位置问题 69.圆圈报数问题 70.计算一个字符串长度 71.编写输入/输出函数 72.创建链表 73.反向输出链表 74.连接两个链表 75.算一道简单题目 76.调用函数求1/2+1/4+...+1/n 77.填空练习(指向指针的指针) 78.找到年龄最大的人 79.字符串排序 80.海滩猴子分桃 81.已知公式条件求数字 82.八进制转换为十进制 83.求0-7所能组成的奇数个数 84.由两个素数之和表示的偶数 85.判断一个素数能被几个9整除 86.两个字符串连接程序 87.结构体变量传递 88.读取数字的整数值并打印出该值个数的* 89.数据加密 90.专升本一题 91.时间函数举例1 92.时间函数举例2 93.时间函数举例3 94.一个猜数游戏 95.家庭财务管理小程序 96.计算字符串中子串出现的次数 97.输入字符并保存到磁盘 98.字符串转换成大写字母并输出保存 99.文件操作应用1 100.文件操作应用2

69,377

社区成员

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

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