今天在看Linux系统编程这本书的代码的时候看到了__GNUC__,不太清楚这个宏所以去查了一下,以此记录。GNU C预定义了一系列的宏,这些宏都是以双下划线开始的,这里只讲一下__GNUC__  __GNUC_MINOR__ __GNUC_PATCHLEVEL__,完整的GNU C的预定义宏可以到这里查看:

https://gcc.gnu.org/onlinedocs/gcc-5.1.0/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros

__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__);
#endifreturn 0;
}

预编译以后的文件函数部分:

int main()
{printf("__GNUC__ = %d\n",4);printf("__GNUC_MINOR__ = %d\n",9);printf("__GNUC_PATCHLEVEL__ = %d\n",2);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 > 30200printf("gcc > 3.2.0\n");//...
#endifreturn 0;
}

好啦,对__GNUC__这个预定义的宏变量算是有了一个基本的了解,作用是用来针对特定版本的gcc进行编写代码,至于其他预定义的宏呢可以去本文刚开始的时候给出的网站上查看,他们各自的作用也都写的非常清楚。

linux gcc 宏定义 __GNUC__ __GNUC_MINOR__ 版本区分相关推荐

  1. linux shell 宏定义_Linux系统和Shell命令行简介,走上数据分析之路

    122Linux系统和Shell命令行简介,走上数据分析之路 本节作者:刘永鑫 中国科学院遗传与发育生物学研究所 版本1.0.2,更新日期:2020年8月31日 本项目永久地址:https://git ...

  2. linux makefile 宏定义

    0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助博客总结 ...

  3. linux arm64 宏定义,ARM64 芯片的 Jiffies 更新流程

    最近在调试 arm64 机器时遇到了一个比较蛋疼的时钟问题,这个时钟问题会导致在部分机器类型上导致无法启动,为了深入了解并解决掉这个问题,特定决定研究一下整个 jiffies 的更新逻辑过程,本篇文章 ...

  4. linux c 宏定义 #define _GNU_SOURCE 含义

    今天我必须要使用 basename 函数,使用man手册查询了一下这个函数 man 3 basename 发现一个奇怪的信息 名称 basename,dirname-分析路径名组件 简介 #inclu ...

  5. Linux如何查看信号宏定义,转  LINUX 调试宏定义

    在include\linux下新建一个debug头文件debug_if.h,鉴于KERN_WARNING之类的宏 在include\linux\kernel.h,因此将debug_if.h包含到ker ...

  6. linux shell 宏定义_linux内核修炼之系统调用

    fork()这个系统调用是有两个返回值的,在子进程中的返回值是0,在父进程中的返回值是PID,如下 图 fork一次 返回两次 关于0x80中断和特权级检查 在mian函数的sched_init()函 ...

  7. linux shell 宏定义_一篇教会你写90%的shell脚本

    shell是外壳的意思,就是操作系统的外壳.我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包括ls.cd.pwd等等.总结来说,Shell是一个命令解释器,它通过接 ...

  8. linux驱动 打印变量,linux驱动 内核函数 变量 宏定义

    insmod modprobe(自动检测 模块加载时需要的别的模块) rmmod 用户空间工具, 加载模块到运行中的内核以及去除它们. #include module_init(init_functi ...

  9. 你真的了解宏吗:浅谈宏定义(#define语句)

    简单聊下宏呗 写在前面: 宏定义 语法 1. 宏的作用范围 2.宏替换的原则 4. 宏函数申明 5. 宏中的 "#" 和 "##" #的用法 ##的用法 6. ...

最新文章

  1. Python爬虫学习(1)
  2. python字符串与列表与运算_[Python学习笔记1]Python语言基础 数学运算符 字符串 列表...
  3. day 45 SQLAlchemy,和增删查改
  4. 苹果错误分析报告preferreuserinterface_20182019年苹果产业链分析报告
  5. 卷积神经网络反向传播算法
  6. 爬取天天基金排行榜上的基金信息
  7. 周鸿祎反流氓的基本商业逻辑(ZZ)
  8. 去掉任务栏中SATA硬盘的安全删除硬件图标
  9. 蓝桥杯2020年第十一届C/C++B组(第一次)省赛习题题解
  10. 2023年有哪些值得推荐的蓝牙耳机?小米|南卡|JBL等等高性价比蓝牙耳机推荐
  11. 旷视科技经典文字检测EAST
  12. 元素水平垂直居中的六种方式
  13. 玩客云通过openwrt作为旁路由
  14. Grapher如何显示与绘图线成角度的线图标签丨使用教程
  15. 计算机专业课科目,考研计算机专业课有哪些科目
  16. 594. 最长和谐子序列--Python
  17. 机器学习初级算法之决策树
  18. java顺序查找法 监视器_java算法:顺序查找(有监视哨和无监视哨)
  19. 线段树进阶之清风拂面
  20. 高科路由器有虚拟服务器设置吗,高科路由器怎么设置 -电脑资料

热门文章

  1. 计算机组成原理 — IPMI/BMC
  2. DPDK — EAL 环境抽象层
  3. VScode操作记录
  4. tls 流量画像——直接使用图像处理的思路探索,待进一步观察
  5. DNS区域主从复制。。
  6. dp,px,pt,sp 的区别 以及dp 和 px 互转
  7. matlab 设置路径 Linux
  8. entity framework 6 我写了一个公用数据类
  9. 用自定义代码分析来标准开发人员的开发规范
  10. Windows2003实用技巧