基于整数溢出的GCC优化

2023-12-13

最近我讨论了有人想像这样检查signed int 溢出if (A + B < 2 * max(A, B))。让我们暂时忽略逻辑本身是错误的,并在 C/C++ 上下文中讨论有符号整数溢出。 (我相信这完全继承了C标准的这一部分)。

哪些类型的需要有符号整数溢出的检查将被当前的 GCC 优化掉,哪些不会?

由于原文的表述不是那么好,并且显然存在争议,我决定稍微改变一下问题,但将原文保留在下面。

下面使用的所有示例均经过测试 gcc 版本4.7.2 (Debian 4.7.2-5)并使用编译-O3

也就是说,它是未定义的,GCC 臭名昭著地使用它来执行一些分支简化。我想到的第一个例子是

int i = 1;
while (i > 0){
    i *= 2;
}

这会产生无限循环。这种优化的另一种情况是

if (A + 2 < A){
    /* Handle potential overflow */
}

其中,假设A是有符号整型,溢出分支被完全删除。

更有趣的是,有些情况很容易provable整数溢出,保持不变,例如

if (INT_MAX + 1 < 0){
    /* You wouldn't write this explicitly, but after static analysis the program
       could be shown to contain something like this. */
}

这会触发您所期望的二进制补码表示的分支。同样,此代码使条件分支保持不变

int C = abs(A);
if (A + C < 0){
    /* For this to be hit, overflow or underflow had to happen. */
}

现在的问题是,是否存在一种大致类似于if (A + B < C) or if (A + B < c),那会被优化掉吗?当我在写这篇文章之前进行谷歌搜索时,似乎最后一个片段应该被优化掉,但是我无法在不显式使用常量操作的溢出检查中重现这种错误。


许多编译器会将涉及有符号整数或指针的表达式替换为“false”,例如

a + 1 < a // signed integer a
p + 1 < p // Pointer p

当表达式仅在未定义行为的情况下才为真时。另一方面,这允许

for (char* q = p; q < p + 2; ++q) ...

要内联,替换 q = p 和 q = p + 1,而不进行任何检查,所以这是一件好事。

if (A + abs (A) < 0)

对于许多编译器来说可能太复杂了。请注意,对于无符号整数,没有未定义的行为。因此,使用带 64 位指针的无符号 32 位整数的循环往往会比必要的速度慢,因为必须考虑回绕行为。对于无符号 32 位整数和 64 位指针,有可能

&p [i] > &p [i+1]

没有未定义的行为(不包括 64 位整数或 32 位指针)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于整数溢出的GCC优化 的相关文章

  • MVC 重定向到没有控制器的视图

    希望应该是一个简单的 我创建了一个通用错误视图 当整个站点的操作方法内发生异常时 我想显示该视图 我创建了一个部分页面 所有导航都位于其中 因此我不需要在此视图上使用控制器 那么如何从控制器内的操作方法重定向到它 像这样的东西 HttpPo
  • 扫描文本文件时如何跳过行?

    我想扫描一个文件并在阅读之前跳过一行文本 我试过 fscanf pointer n struct test i j 但这个语法只是从第一行开始 我可以使用 scanf 使用以下指令跳过行 fscanf config file n n 格式字
  • 为什么派生类不使用基类的operator=(赋值运算符)?

    以下是实际问题的简化版本 而不是打电话Base operator int 代码似乎生成了一个临时的Derived对象并复制它 既然函数签名似乎完美匹配 为什么不使用基本赋值运算符 这个简化的示例没有显示任何不良影响 但原始代码在析构函数中有
  • 通过单个 GPIO 引脚转储闪存

    我正在使用 Infineon 的 XMC4500 Relax Kit 并尝试通过单个 GPIO 引脚提取固件 我非常天真的想法是通过 GPIO 引脚一次转储一位 然后用逻辑分析仪以某种方式 嗅探 数据 伪代码 while word by w
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 通过引用传递时取消引用指针

    当通过引用传递给函数时取消引用指针时会发生什么 这是一个简单的例子 int returnSame int example return example int main int inum 3 int pinum inum std cout
  • rand() 播种与 time() 问题

    我很难弄清楚如何使用 rand 并使用 Xcode 用 time 为其播种 我想生成 0 到 1 之间的随机十进制数 该代码为我提供了元素 1 和 2 看似随机的数字 但元素 0 始终在 0 077 左右 有什么想法吗 我的代码是 incl
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • 使用反射获取基类的受保护属性值

    I would like to know if it is possible to access the value of the ConfigurationId property which is located in the base
  • .net Framework (.net 4.0) 中定义 Base 3 数字的类

    我正在寻找一些可以用来定义 3 基数 三进制数 的类 有什么我可以在 net 框架中使用的东西或者我需要写一些东西吗 谢谢你的帮助 您可以使用解析Convert ToInt32 s base http msdn microsoft com
  • 导出到 CSV 时 Gridview 出现空行

    这个问题是由进一步讨论引发的这个问题 https stackoverflow com questions 6674555 export gridview data into csv file 6674589 noredirect 1 com
  • 指示泛型返回动态类型的对象

    这个问题是我原来问题的后续问题here https stackoverflow com questions 2541184 using a type object to create a generic 假设我有以下泛型类 简化 class
  • Microsoft.Graph - 如何从具有不同用户名的共享邮箱发送?

    我目前正在将使用 SMTP 的服务代码移植到 Office 365 通过 SMTP 我可以使用 发件人 字段在来自共享收件箱的邮件上设置不同的用户名 同时保留共享电子邮箱地址 这似乎无法通过 Office 365 运行 其工艺流程为 客户填
  • 线程安全的 C++ 堆栈

    我是 C 新手 正在编写一个多线程应用程序 不同的编写者将对象推入堆栈 读者将它们从堆栈中拉出 或至少将指针推入对象 C 中是否有任何内置结构可以在不添加锁定代码等的情况下处理此问题 如果没有 那么 Boost 库呢 EDIT 你好 感谢您
  • 如何不在类中实现接口的功能?

    面试时面试官问了我以下问题 但我不知道这个问题的答案是什么 请帮忙 如果我不想 我必须做什么 在我的类中实现一个函数 在接口中声明为 由我班实施 Edited 我正在使用 NET 和 C 如果有人可以提供 C 示例代码示例 那就太好了 Th
  • 如何将字符串转换为 Indian Money 格式?

    我正在尝试将字符串转换为印度货币格式 例如如果输入为 1234567 则输出应为 12 34 567 我编写了以下代码 但它没有给出预期的输出 CultureInfo hindi new CultureInfo hi IN string t
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 为什么C语言中可以使用多个分号?

    在 C 中我可以执行以下操作 int main printf HELLO WORLD 它有效 这是为什么 我个人的想法 分号是一个 NO OPERATION 来自维基百科 指示符 拥有一大串分号与拥有一个分号并告诉 C 语句已结束具有相同的
  • 为什么 C# 接口名称前面加上“I”

    这种命名约定背后的基本原理是什么 我没有看到任何好处 额外的前缀只会污染 API 我的想法与康拉德一致response https stackoverflow com a 222502 9898与此相关的question https sta
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows

随机推荐

  • ImageMagick 未被授权将 PDF 转换为图像

    我有一个程序 需要使用 Image Magick 将 PDF 转换为图像 我这样做是使用subprocess包裹 cmd magick convert density 300 pdfFile str rangeTuple 0 str ran
  • Scrapy - 蜘蛛抓取重复的网址

    我正在抓取搜索结果页面并从同一页面抓取标题和链接信息 作为一个搜索页面 我也有到下一页的链接 我已在 SgmlLinkExtractor 中指定允许这些链接 问题的描述是 在第1页中 我找到了Page2和Page3的链接进行爬行 并且效果很
  • Parsley 远程和附加参数

    我正在尝试将远程验证器与欧芹一起使用 但我似乎无法通过请求发送附加数据 有问题的字段是电子邮件字段 我想将其发送到服务器以查看电子邮件地址是否 可用 另外 我需要发送服务器所需的 id 参数 id 参数嵌入在我的表单中的 主机 字段中 因此
  • Mongoose 调试写入 STDERR?

    有谁知道 有关于为什么 mongoose 将其调试日志写入 stderr 的信息 无论如何可以将其写入标准输出吗 调试选项接受函数而不是布尔值 mongoose set debug function collection method pa
  • 使用 AVX2 指令选择性地异或列表的元素

    我想用 AVX2 指令加速以下操作 但我找不到方法 我得到了一个大数组uint64 t data 100000 uint64 t 和一个数组unsigned char indices 100000 字节数 我想输出一个数组uint64 t
  • grep 使用具有多种模式的字符向量

    我正在尝试使用grep测试字符串向量是否存在于另一个向量中 并输出存在的值 匹配模式 我有一个像这样的数据框 FirstName Letter Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6
  • ClassLoaders.callStaticFunction Java Eclipse 的 InvokingTargetException

    我创建了一个使用 ReverseXSL API 将文本转换为 xml 的程序 该程序将由应用程序通过调用静态方法 静态 int 变换XSL 我能够通过从 Eclipse 运行来执行并生成输出 但是 当我使用应用程序运行程序 jar 时 它卡
  • 当parentID和childID在同一个表上时如何删除级联?

    我有一个名为members的mysql表 它基本上有两列 parentID and childID 这样我就可以根据这两列创建一个层次树 例如 parentID ChildID 1 2 2 3 3 4 将在我的应用程序中生成一棵树paren
  • 无法使用 NdefFormatable 格式化 NFC 卡

    我正在使用 NdefFormatable 类来格式化我的 NFC 卡 代码如下 NdefFormatable formatable NdefFormatable get tag 但我得到的可格式化引用为空 我检查了 get tag 方法内运
  • 图像未加载到画布上

    我的问题是 我在将本地托管的图像加载到画布上时遇到问题 我尝试过使用 XAMPP 在本地将代码托管在 Web 服务器上 但 LightBlue jpg 图像似乎永远无法加载 但是 当我使用网站上的外部图像时 代码可以完美运行 我在下面提供了
  • 将 Android 屏幕方向锁定为横向

    我正在开发一个 Android 应用程序 其一个功能是将屏幕方向锁定为横向 我想将此方向更改应用于手机中的所有 Android 应用程序 我正在使用这个代码 private void lockScreenOrientation if mSc
  • 在 Inno Setup 中创建使用命令行参数执行程序的快捷方式

    我有一个问题 我正在为一个程序做一个自定义安装程序 原始安装程序在桌面上创建一个快捷方式 快捷方式的目标如下 C Program Files Soft name soft exe soft run 在 Inno Setup 脚本中我使用以下
  • 用于软件清单的 PowerShell

    我想知道如何获得包含已安装软件和电脑名称的两列 Path C Gabriel LogPath C Gabriel Select Name Directory Name Outlook Expression Get WmiObject Cla
  • 在CSS视觉格式模型中,“元素的流动”是什么意思?

    In CSS2 第 9 3 节 定位方案 一个元素称为流出如果它是浮动的 绝对定位的或者是根元素 一个元素称为in flow如果没有流出 这元素的流动A 是由 A 和最近的流出祖先为 A 的所有流入元素组成的集合 我能明白什么流出 and
  • 如何通过空格字符拆分列表中的字符串

    所以stdin将一串文本返回到一个列表中 多行文本都是列表元素 你如何将它们全部拆分成单个单词 mylist this is a string of text n this is a different string of text n a
  • Firebase 托管:功能无法与 ServerMiddleware (Vue/Nuxt) 一起使用

    我正在构建一个利用 ServerMiddleware 仅在客户端呈现某些页面的项目 我无法找到另一种在没有 ServerMiddleware 的情况下使其正常工作的方法 刷新页面等问题 问题 不幸的是 每次我尝试通过 firebase部署
  • 在运行时更改应用程序MainForm [重复]

    这个问题在这里已经有答案了 我想在单击按钮时重新启动主表单 例如 In program cs Application Run new MainForm data In MainForm cs private void btn1 Click
  • 如何更改 csharp 项目(Visual Studio / msbuild 机器)中的源文件编码?

    有没有办法强制 VS 始终使用 Unicode 而不是奇怪的 ISO 之类的东西 我正在 Vista 波兰语区域 上使用 Visual Studio 2008 开发 winapp csproject 当我在 Win Server 2003
  • 当 apachectl 开始打开共享对象文件时

    我尝试使用 tar 文件安装 apache 网络服务器 因此 我下载了 httpd 2 4 tar 文件并解压 then I 尝试安装 1 configure prefix usr local apache 但是 抛出这个错误 config
  • 基于整数溢出的GCC优化

    最近我讨论了有人想像这样检查signed int 溢出if A B lt 2 max A B 让我们暂时忽略逻辑本身是错误的 并在 C C 上下文中讨论有符号整数溢出 我相信这完全继承了C标准的这一部分 哪些类型的需要有符号整数溢出的检查将