请教一个C 语言#ifdef 的问题

[复制链接]
1683|12
 楼主| suxilong 发表于 2018-7-18 14:52 | 显示全部楼层 |阅读模式
目的: 为了定义一个宏,然后根据宏 决定使用哪个函数  (函数名 是一样的 ,只是实现的内容不同)

在一个.c 文件下
  1. #ifdef A_ENABLE
  2. void a(uint8 i)
  3. {

  4.    ....

  5. }
  6. #else
  7. void a(uint8 *i)
  8. {

  9.    ....
  10. }
  11. #endif


在对应的.h 文件下
  1. #ifdef A_ENABLE
  2. void a(uint8 i);
  3. #else
  4. void a(uint8 *i);
  5. #endif


开启 A_ENABLE 的宏后, 在 某个地方 调用了函数      a(5);
结果编译的时候总是报错 :error: unknown type name 'uint8' void a(uint8 *i);

奇怪的是 我在#else 下面随便乱写写代码,编译的时候也会报哪里的错, 但不是宏启动后, #else 下面就不列入编译吗?

请问#ifdef 是不是不可以用来  区分同样名字的函数呢?
df_flying 发表于 2018-7-18 15:09 | 显示全部楼层
不清楚为啥要分开?就用一个uint8_t *i,可以直接代替 uint8_t i 啊,i[0]就是一个第一个,那边传一个变量地址(&i)就好了啊。
你这代码这样写,换个人读,鬼知道哪里用i  哪里用*i

评论

@df_flying :没使用keil IDE, 直接是敲代码 make ~~~~  发表于 2018-7-20 17:48
@suxilong :加在h文件其实也不一定,这个跟编译器有一定的关系,也可以写在设置的默认宏定义中KEIL是 Options -> C/C++ -> Preprocessor Symbols 的Define  发表于 2018-7-18 15:35
@suxilong :这个可以,放在h文件前面,或者另外一个h文件中,加载在h文件里, 你用keil524a版本添加一个宏定义未定义变灰色的功能,可以很清楚看到哪个有效,哪个无效(代码变灰了)  发表于 2018-7-18 15:30
这是 举例,不要纠结 举的例子, 这里只讨论 #ifdef 能否 用来 区分 同名函数 ?  发表于 2018-7-18 15:19
wsmysyn 发表于 2018-7-18 15:14 | 显示全部楼层
1、用#ifdef...#else...#endif肯定是可以进行选择性编译代码的

2、和你的使能开关语句(#define A_ENABLE)的位置有关,要在你定义的选择代码之前把开关包含进去,放在后边的话,是不行的。
 楼主| suxilong 发表于 2018-7-18 15:20 | 显示全部楼层
wsmysyn 发表于 2018-7-18 15:14
1、用#ifdef...#else...#endif肯定是可以进行选择性编译代码的

2、和你的使能开关语句(#define A_ENABLE ...

可以 我放在main 函数最前面还是不行~~~

如果查找 谁是最先启动的地方吗 ?
wsmysyn 发表于 2018-7-18 15:24 | 显示全部楼层
本帖最后由 wsmysyn 于 2018-7-18 15:36 编辑
suxilong 发表于 2018-7-18 15:20
可以 我放在main 函数最前面还是不行~~~

如果查找 谁是最先启动的地方吗 ? ...

最保险的是放在声明的那个h文件函数声明的前边定义;然后函数体所在的.c文件include这个头文件,这样保证编译开关都是在编译a函数之前被编译器看到。下边是keil里边的实验

即使放在main函数最开头,应该还不能保证编译器最先编译的是哪个文件.c文件,可能是你的a函数所在c文件先编译,main函数所在的后编译的。
导致编译器看不到使能开关,选择了另一个函数,而你调用的是没有被编译函数,所以错了

编译顺序可能根据路径和文件名,有关系吧,具体没有验证





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| suxilong 发表于 2018-7-18 16:57 | 显示全部楼层
df_flying 发表于 2018-7-18 15:09
不清楚为啥要分开?就用一个uint8_t *i,可以直接代替 uint8_t i 啊,i[0]就是一个第一个,那边传一个变量 ...

谢谢你! 是 我自己搞错了, 我定义在一个.h 中, 但是 使用到这个宏的 那个文件 没有包含这个.h  ,导致误以为启动了这个宏~~~~实际没有启动
 楼主| suxilong 发表于 2018-7-18 16:59 | 显示全部楼层
wsmysyn 发表于 2018-7-18 15:24
最保险的是放在声明的那个h文件函数声明的前边定义;然后函数体所在的.c文件include这个头文件,这样保证 ...

谢谢你 !
即便 定义在main  中, 也不能保证 完全正确,
必须定义在 使用宏的文件之前,

即 可以定义在一个.h 文件中, 但是 必须 确保 使用到这个宏的那个文件例如.c 必须   没有包含这个.h  ,

不然容易导致误以为启动了这个宏~~~~实际没有启动
wsmysyn 发表于 2018-7-18 18:06 | 显示全部楼层
suxilong 发表于 2018-7-18 16:59
谢谢你 !
即便 定义在main  中, 也不能保证 完全正确,
必须定义在 使用宏的文件之前,

嗯,是的;开关一定是在那段宏之前。
编译的顺序,不能保证main文件最先被编译;

一般一个模块分成1个.h,1个.c;
.h -- 一般放.c中的函数声明,宏定义,编译开关,或者全局变量等;.h做防止重复包含操作
.c -- 将这个.h在文件最开始包含进来;然后是函数体现实,局部变量,静态函数等等

这样做一般没遇到什么问题。很直观。

之前有参考过google和华为的C/C++编程规范,学习了一下。收益不少
mcu5i51 发表于 2018-7-19 08:19 | 显示全部楼层
#ifdef A_ENABLE
#define My_t u8
#else
#define My_t u8*
#endif

a(Mt_t i)...
这样行不,用typedef或宏定义一个自己的变量类型
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:没有最差,只有最懒

55

主题

340

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部