__builtin_constant_p 常量检查函数

__builtin_constant_p 详细介绍

功能:
__builtin_constant_p 是 GCC (GNU Compiler Collection) 提供的一个内置函数,用于在编译时检测一个表达式是否是常量。它返回一个整型值:

  • 如果表达式 exp 是编译时常量,则返回 1。
  • 否则,返回 0。

语法:

int __builtin_constant_p(exp);

其中 exp 是需要判定的表达式。

工作原理:
__builtin_constant_p 并不是一个普通的函数,它实际上是 GCC 编译器在编译时进行优化的一部分。它不会影响代码的逻辑,只是在编译过程中起作用。

使用场景

  • 宏定义中的常量判断

在宏定义中使用 __builtin_constant_p 可以帮助优化和保证代码安全。例如,你可以根据是否是常量来选择不同的实现路径:

#define MY_MAX(a, b) (__builtin_constant_p(a) && __builtin_constant_p(b) ? ((a) > (b) ? (a) : (b)) : runtime_max((a), (b)))int runtime_max(int a, int b) {return (a > b) ? a : b;
}

在这个例子中,如果 a 和 b 都是编译时常量,宏将选择用 a 和 b 的值直接进行常量计算;否则,将调用运行时的 runtime_max 函数。

  • 编译期优化

在实现某些库或者系统底层代码时,编写者可以利用 __builtin_constant_p 来让编译器在编译时就进行常量折叠,从而提高运行时性能。

#define ARRAY_SIZE(arr) (__builtin_constant_p(sizeof(arr) / sizeof((arr)[0])) ? sizeof(arr) / sizeof((arr)[0]) : -1)

这个宏用于获取数组的大小,如果传递的参数是一个数组,sizeof(arr) 是一个编译时常量,__builtin_constant_p 会返回 1。否则,它会返回 -1 来指示错误。

  • 安全性检查

在一些场景下,你可能希望确保某个值在编译时已经确定,以保障代码的安全性和稳定性。例如,控制进程的堆栈空间大小:

#define SET_STACK_SIZE(size) (__builtin_constant_p(size) ? (actual_stack_size = (size)) : (void)0)

在这个宏中,如果 size 不是编译时常量,宏将不会进行任何操作,从而避免了潜在的错误设置。

示例代码1

以下是一些完整的示例代码,演示如何使用 __builtin_constant_p

#include <stdio.h>#define IS_CONSTANT(expr) (__builtin_constant_p(expr) ? "是编译时常量" : "不是编译时常量")int main() {int a = 10;const int b = 20;printf("a + 5 %s\n", IS_CONSTANT(a + 5));printf("b + 5 %s\n", IS_CONSTANT(b + 5));printf("3.14159 %s\n", IS_CONSTANT(3.14159));printf("a %s\n", IS_CONSTANT(a));return 0;
}

在这个例子中:

  • a + 5 不是编译时常量,因为 a 的值在运行时才能确定。
  • b + 5 是编译时常量,因为 b 是 const 类型,其值在编译时确定。
  • 3.14159 是编译时常量。
  • a 本身不是编译时常量。

示例代码2

#define ___wait_is_interruptible(state)					\(!__builtin_constant_p(state) ||				\state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE)

在这个例子中:

这个宏用于判断一个给定的任务状态 state 是否是可中断状态。

  • ___wait_is_interruptible(state):这是一个宏定义,接收一个参数 state,表示任务的状态。

  • (!__builtin_constant_p(state) || ...)

    • __builtin_constant_p(state):判断 state 是否是编译时常量。
    • !__builtin_constant_p(state):取反,表示 state 不是 编译时常量。
    • ... || ...:逻辑或运算,表示只要其中一个条件为真,整个表达式就为真。
  • state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE

    • 判断 state 是否等于 TASK_INTERRUPTIBLE 或者 TASK_KILLABLE。 这些状态通常表示任务是可以被中断或者杀死的。

这个宏的逻辑可以概括为以下两种情况

  • 如果 state 不是 编译时常量,那么宏直接返回 。这意味着在运行时才能确定状态的情况下,默认认为它是可中断的。
  • 如果 state 是编译时常量,那么宏会检查它是否等于 TASK_INTERRUPTIBLE 或 TASK_KILLABLE,如果是则返回 ,否则返回 

 

注意事项

  1. 兼容性:
    __builtin_constant_p 是 GCC 特有的扩展,所以不保证在其他编译器(如 MSVC、Clang 等)上能编译通过。需要跨平台时应谨慎使用。

  2. 编译时 vs 运行时常量:
    __builtin_constant_p 只能检查编译时常量,不能用于检查运行时常量。因此在某些时候必须特别注意它的限制。

通过对 __builtin_constant_p 的理解和应用,你可以在编写高效、优化的代码时拥有更多的灵活性和控制权。希望这个详细的解释能够满足你的需求!如果有其他问题,请随时告诉我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/41246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FairJob:促进在线广告系统公平性研究

在人工智能&#xff08;AI&#xff09;与人类动态的交汇处&#xff0c;既存在机遇也存在挑战&#xff0c;特别是在人工智能领域。尽管取得了进步&#xff0c;但根植于历史不平等中的持续偏见仍然渗透在我们的数据驱动系统中&#xff0c;这些偏见不仅延续了不公平现象&#xff0…

Centos新手问题——yum无法下载软件

起因&#xff1a;最近在学习centos7&#xff0c;在VM上成功安装后&#xff0c;用Secure进行远程登陆。然后准备下载一个C编译器&#xff0c;看网络上的教程&#xff0c;都是用yum来下载&#xff0c;于是我也输入了命令&#xff1a; yum -y install gcc* 本以为会自动下载&…

docker部署redis/mongodb/

一、redis 创建/root/redis/conf/redis.conf 全部执行命令如下 docker run -it -d --name redis -p 6379:6379 --net mynet --ip 172.18.0.9 -m 400m -v /root/redis/conf:/usr/local/etc/redis -e TXAsia/Shangehai redis redis-server /usr/local/etc/redis/redis.conf 部署…

C#——密封类详情

密封类 密封类是密封方法的扩展&#xff0c;用于确保某个类不会被继承。在C#中&#xff0c;你可以使用sealed关键字来声明一个密封类。 public sealed class SealedClass {// 类成员定义 } 如果使用密封类继承的话&#xff0c;程序会报错&#xff01;&#xff01;&#xff0…

01:spring

文章目录 一&#xff1a;常见面试题1&#xff1a;什么是Spring框架&#xff1f;1.1&#xff1a;spring官网中文1.2&#xff1a;spring官网英文 2&#xff1a;谈谈自己对于Spring IOC和AOP的理解2.1&#xff1a;IOCSpring Bean 的生命周期主要包括以下步骤&#xff1a; 2.2&…

解决微信读书和Apple Books导入epub电子书不显示图片的问题

title: 解决微信读书和Apple Books导入epub电子书不显示图片的问题 tags: 个人成长 categories:杂谈 最近找到一本很喜欢的书的电子版的epub版&#xff0c;发现无论是导入微信读书&#xff0c;还是Apple家的Books, 都无法正常显示图片。 于是我用calibre打开epub电子书&#x…

安卓虚拟位置修改

随着安卓系统的不断更新&#xff0c;确保软件和应用与最新系统版本的兼容性变得日益重要。本文档旨在指导用户如何在安卓14/15系统上使用特定的功能。 2. 系统兼容性更新 2.1 支持安卓14/15&#xff1a;更新了对安卓14/15版本的支持&#xff0c;确保了软件的兼容性。 2.2 路…

linux中可执行文件为什么不能拷贝覆盖

对于一个普通的文件&#xff0c;假如有两个文件&#xff0c;分别是file和file1&#xff0c;我们使用 cp file1 file的方式使用file1的内容来覆盖file的内容&#xff0c;这样是可以的。 但是对于可执行文件来说&#xff0c;当这个文件在执行的时候&#xff0c;是不能通过cp的方…

将 KNX 接入 Home Assistant 之四 功能测试

一&#xff1a;测试标准的KNX网关功能 测试软件识别是否正常 可以看到再ETS6和ETS5上都能正常识别 测试数据收发 可以正常发送数据 测试配置设备参数&#xff08;下载配置&#xff09; 可以看出&#xff0c;在ETS5上是可以正常下载参数的 但是 ETS6下载是失败的&#xff…

Pandas 学习笔记(四)--CSV文件

CSV文件 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。 读取与写入 读取csv文件 i…

可视化作品集(08):能源电力领域

能源电力领域的可视化大屏&#xff0c;有着巨大的用武之地&#xff0c;不要小看它。 监控能源生产和消耗情况&#xff1a; 通过可视化大屏&#xff0c;可以实时监控能源生产和消耗情况&#xff0c;包括发电量、能源供应情况、能源消耗情况等&#xff0c;帮助管理者及时了解能…

C语言 | Leetcode C语言题解之第218题天际线问题

题目&#xff1a; 题解&#xff1a; struct pair {int first, second; };struct Heap {struct pair* heap;int heapSize;bool (*cmp)(struct pair*, struct pair*); };void init(struct Heap* obj, int n, bool (*cmp)(struct pair*, struct pair*)) {obj->heap malloc(si…

调制信号识别系列 (一):基准模型

调制信号识别系列 (一)&#xff1a;基准模型 说明&#xff1a;本文包含对CNN和CNNLSTM基准模型的复现&#xff0c;模型架构参考下述两篇文章 文章目录 调制信号识别系列 (一)&#xff1a;基准模型一、论文1、DL-PR: Generalized automatic modulation classification method b…

软件架构之操作系统

第 2 章操作系统 本章主要介绍操作系统的基本概念及其形成、发展历史和主要类型&#xff0c;并指出操作系统的5 大管理功能。掌握操作系统原理的关键在于深入理解“一个观点、两条线索”。一个观点是以资源管理的观点来定义操作系统&#xff1b;两条线索是指操作系统如何管理计…

【计算机毕业设计】020基于weixin小程序订餐系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

100359.统计X和Y频数相等的子矩阵数量

1.题目描述 给你一个二维字符矩阵 grid&#xff0c;其中 grid[i][j] 可能是 X、Y 或 .&#xff0c;返回满足以下条件的子矩阵数量&#xff1a; 包含 grid[0][0]X 和 Y 的频数相等。至少包含一个 X。 示例 1&#xff1a; 输入&#xff1a; grid [["X","Y",…

密室逃脱——收集版修改测试

一、原版修改 1、导入资源 Unity Learn | 3D Beginner: Complete Project | URP 2、设置Scene 删除SampleScene&#xff0c;打开UnityTechnologies-3DBeginnerComplete下的MainScene 3、降低音量 (1) 打开Hierarchy面板上的Audio降低音量 (2) 打开Prefabs文件夹&#xf…

lnmp php7 安装ssh2扩展

安装ssh2扩展前必须安装libssh2包 下载地址: wget http://www.libssh2.org/download/libssh2-1.11.0.tar.gzwget http://pecl.php.net/get/ssh2-1.4.tgz &#xff08;这里要换成最新的版本&#xff09; 先安装 libssh2 再安装 SSH2: tar -zxvf libssh2-1.11.0.tar.gzcd libss…

【日志信息管理】管理日志信息的类

日志用于记录程序的执行记录包括程序的出错记录&#xff0c;程序致命退出原因&#xff0c;程序的正常执行记录。这样我们就可以很快的察觉程序的错误原因、执行状况等等&#xff0c;因此管理日志信息是非常重要的。 日志一般由以下部分组合&#xff1a; 日志时间、日志等级、…

Java 基础--File - IO流(2)

I/O流 定义 数据从硬盘流向内存为输入流&#xff0c;数据从内存流向硬盘为输出流。输入也叫读取数据&#xff0c;输出也叫写出数据。 IO分类 1.按照数据的流向分为&#xff1a;输入流和输出流 ①输入流&#xff1a;把数据从其他设备上读取到内存中的流 ②输出流&#xff1…