打印

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

[复制链接]
1444|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
目的: 为了定义一个宏,然后根据宏 决定使用哪个函数  (函数名 是一样的 ,只是实现的内容不同)

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

   ....

}
#else
void a(uint8 *i)
{

   ....
}
#endif


在对应的.h 文件下
#ifdef A_ENABLE
void a(uint8 i);
#else
void a(uint8 *i);
#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

使用特权

评论回复
评论
suxilong 2018-7-20 17:48 回复TA
@df_flying :没使用keil IDE, 直接是敲代码 make ~~~~ 
df_flying 2018-7-18 15:35 回复TA
@suxilong :加在h文件其实也不一定,这个跟编译器有一定的关系,也可以写在设置的默认宏定义中KEIL是 Options -> C/C++ -> Preprocessor Symbols 的Define 
df_flying 2018-7-18 15:30 回复TA
@suxilong :这个可以,放在h文件前面,或者另外一个h文件中,加载在h文件里, 你用keil524a版本添加一个宏定义未定义变灰色的功能,可以很清楚看到哪个有效,哪个无效(代码变灰了) 
suxilong 2018-7-18 15:19 回复TA
这是 举例,不要纠结 举的例子, 这里只讨论 #ifdef 能否 用来 区分 同名函数 ? 
板凳
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 函数最前面还是不行~~~

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

使用特权

评论回复
5
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函数所在的后编译的。
导致编译器看不到使能开关,选择了另一个函数,而你调用的是没有被编译函数,所以错了

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





使用特权

评论回复
6
suxilong|  楼主 | 2018-7-18 16:57 | 只看该作者
df_flying 发表于 2018-7-18 15:09
不清楚为啥要分开?就用一个uint8_t *i,可以直接代替 uint8_t i 啊,i[0]就是一个第一个,那边传一个变量 ...

谢谢你! 是 我自己搞错了, 我定义在一个.h 中, 但是 使用到这个宏的 那个文件 没有包含这个.h  ,导致误以为启动了这个宏~~~~实际没有启动

使用特权

评论回复
7
suxilong|  楼主 | 2018-7-18 16:59 | 只看该作者
wsmysyn 发表于 2018-7-18 15:24
最保险的是放在声明的那个h文件函数声明的前边定义;然后函数体所在的.c文件include这个头文件,这样保证 ...

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

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

不然容易导致误以为启动了这个宏~~~~实际没有启动

使用特权

评论回复
8
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++编程规范,学习了一下。收益不少

使用特权

评论回复
9
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

主题

339

帖子

4

粉丝