linuxgcc宏定义__GNUC____GNUC_MINOR__版本区分今天在看Linux系统编程这本书的代码的时候看到了__GNUC__,不太清楚这个宏所以去查了⼀下,以此记录。GNU C预定义了⼀系列的宏,这些宏都是以双下划线开始的,这⾥只讲⼀下__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__,完整的GNU C的预定义宏可以到这⾥查看:
__GNUC__ 、__GNUC_MINOR__ 、__GNUC_PATCHLEVEL__分别代表gcc的主版本号,次版本号,修正版本
号。__GNUC_PATCHLEVEL__是从gcc 3.0以后才有的,在这之前的gcc是没有预定义这个宏的。我们可以⽤gcc --version来查看⾃⼰系统中的gcc版本,现在的gcc版本普遍都是3.0以后了吧,就我的系统⽽⾔,是4.9.2,那么对应的__GNUC__就是
4,__GNUC_MINOR__就是9,__GNUC_PATCHLEVEL__就是2。这⼏个宏的类型都是int,被扩展后,会得到整数的字⾯值。由于是宏,因此我们可以通过只预处理源程序来观察他们的⽂本值。⽐如,只对下⾯这段代码进⾏预处理,预处理(gcc -E)以后是对宏进⾏直接的替换,所以我们就能看到这三个宏的⽂本值:
#include <stdio.h>
int main()
{
#ifdef __GNUC__
printf("__GNUC__ = %d\n",__GNUC__);
#endif
#ifdef __GNUC_MINOR__
printf("__GNUC_MINOR__ = %d\n",__GNUC_MINOR__);
#endif
#ifdef __GNUC_PATCHLEVEL__
printf("__GNUC_PATCHLEVEL__ = %d\n",__GNUC_PATCHLEVEL__);
#endif
return 0;
}
预编译以后的⽂件函数部分:
int main()
{
printf("__GNUC__ = %d\n",4);
printf("__GNUC_MINOR__ = %d\n",9);
printf("__GNUC_PATCHLEVEL__ = %d\n",2);gnu编译器
return 0;
}
这样就很直观地看到,__GNUC__被替换成了4,__GNUC_MINOR__被替换成了9,__GNUC_PATCHLEVEL__替换成了2。
为什么要预定义了这三个宏呢?这是为了⽅便我们在针对特定版本的gcc编译器进⾏代码编写的,⽐如我们的代码要求gcc的版本⾄少在
3.2.0以上,我们就可以写成如下⽅式的条件编译:
/* Test for GCC > 3.2.0 */
#if __GNUC__ > 3 || \
(__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
(__GNUC_MINOR__ == 2 && \
__GNUC_PATCHLEVEL__ > 0)))
printf("gcc > 3.2.0\n");
//...
#endif
注意上⾯把条件编译#if的条件写成了多⾏的时候(和宏定义⼀样,如果宏定义⼀⾏写不完,要在最后加⼀个⾏继续符'\'),每⾏最后的⾏继续符'\'后⾯不能跟任何符号,空格、制表符等都不⾏,他表⽰下⼀⾏的也是并列条件(通常为||或&&的右操作数),通常在编译以前会把⾏继续符'\'以及前⾯的换⾏符都去掉,这样就可以看作是同⼀⾏的了。
当然有的⼈觉得上⾯的条件那么⼤⼀串看起来⾮常不顺眼,理解起来也不容易,这时候我们可以⾃⼰定义⼀个宏GCC_VERSION⽤来表⽰gcc版本,原理也很简单就是把主版本号*10000+次版本号*100+修订版本号,最终⽤这个值来判断gcc的版本号:
#include <stdio.h>
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
int main()
{
/* Test for GCC > 3.2.0 */
#if GCC_VERSION > 30200
printf("gcc > 3.2.0\n");
//...
#endif
return 0;
}
好啦,对__GNUC__这个预定义的宏变量算是有了⼀个基本的了解,作⽤是⽤来针对特定版本的gcc进⾏编写代码,⾄于其他预定义的宏呢可以去本⽂刚开始的时候给出的⽹站上查看,他们各⾃的作⽤也都写的⾮常清楚。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论