#ifdef与#ifdefine()之间的区别

在查阅Linux内核源码的过程中,发现存在两种不同类型的条件编译语句:#ifdef MACRO_A和#if defined(MACRO_A)或#if !defined(MACRO_A)

#ifdef和#ifdefined()之间的区别

实际上,两者并无本质的差别,但后者的应用范围更广,能支持多个预编译变量的检查。

#if defined(MACRO_A) && !defined(MACRO_B)  
#endif 
如果用前者的方式来表达,只能使用嵌套的条件判断
#ifdef(MACRO_A)  
    #ifndef(MACRO_B)  
        ...;  
        ...;  
    #endif  
#end

后来,在源码中又看到了这样的条件语句:

#define CONFIG_RMII            0

在c文件中,这样使用宏定义:

#ifdef CONFIG_RMII
    macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
#else
    macb_writel(macb, USRIO, 0);
#endif

我的编译结果是,不管将CONFIG_RMII设为0或1,编译出来的二进制文件,除了编译时间不同,其他都一样。

这说明对该宏的使用有误。

从网上查了些资料,发现是对#if和#ifdef的区别不清楚所导致。

#if和#ifdef之间的区别

对于#if后面需要是一个表达式,如果表达式为1则调用#if下面的代码。
对于#ifdef后面需要的只是这个值有没有用#define定义,并不关心define的这个值是0还是1。


要使得判别条件#ifdef结果为假,也就是不执行判别条件后面所跟的语句,需要对#ifdef后面所跟的宏使用#undef语句进行声明。



————————————————————————————————————————————————————————————

另外:

经常在内核中看到这样的宏判断:
#ifdef CONFIG_**
....
#endif
比如,init/main.c中有这样的代码:
#ifdef CONFIG_PROC_FS
        proc_root_init();
#endif
这里的意思我知道,就是根据CONFIG_PROC_FS是否定义来选择proc文件系统。
如果选择proc文件系统,在.config中就会有如下内容:
CONFIG_PROC_FS=y

如果要将上面的proc_root_init编译进内核,必须有#define CONFIG_PROC_FS或者编译时使用-DCONFIG_PROC_FS,但这两种方法我在代码中都找不到,难道是CONFIG_PROC_FS=y起作用了


我是这样理解的:
#define CONFIG_PROC_FS 1 是在 include/linux/autoconf.h 中定义的 (autoconf.h 又是通过make menuconfig生成的)
在 顶层的Makefile中 定义了 LINUXINCLUDE.
LINUXINCLUDE    := -Iinclude \
                   $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
           -include include/linux/autoconf.h
在编译 init/main.c时gcc会处理 -include include/linux/autoconf.h,相当于源文件中有 #include "linux/autoconfi.h"语句,此时 init/main.c就可以使用autoconf.h中的个个宏了。

cmd_init/main.o := gcc -m32 -Wp,-MD,init/.main.o.d  -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.1.2/include -D__KERNEL__ -Iinclude -Iinclude2 -I/root/fs_all/kernel/linux-2.6.24/include -include include/linux/autoconf.h -I/root/fs_all/kernel/linux-2.6.24/init -Iinit -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -pipe -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -ffreestanding -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -I/root/fs_all/kernel/linux-2.6.24/include/asm-x86/mach-generic -Iinclude/asm-x86/mach-generic -I/root/fs_all/kernel/linux-2.6.24/include/asm-x86/mach-default -Iinclude/asm-x86/mach-default -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign  -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(main)"  -D"KBUILD_MODNAME=KBUILD_STR(main)" -c -o init/.tmp_main.o /root/   fs_all/kernel/linux-2.6.24/init/main.c


——————————————————————本人也 不太理解,只是转载他人,用来学习,作个总结!

  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值