优化易失性堆栈变量的存储/构造是否合法?

2023-11-24

我注意到 clang 和 gcc 优化了易失性的构造或分配struct在某些情况下,在堆栈上声明。例如,以下代码:

struct nonvol2 {
    uint32_t a, b;
};

void volatile_struct2()
{
    volatile nonvol2 temp = {1, 2};
}

Compiles在 clang 上:

volatile_struct2(): # @volatile_struct2()
  ret

另一方面,gcc 不会删除存储,尽管它确实将两个隐含存储优化为单个存储:

volatile_struct2():
        movabs  rax, 8589934593
        mov     QWORD PTR [rsp-8], rax
        ret

奇怪的是,clang 不会将易失性存储优化为单个int多变的:

void volatile_int() {
    volatile int x = 42;
}

编译为:

volatile_int(): # @volatile_int()
  mov dword ptr [rsp - 4], 1
  ret

此外,具有 1 个成员而不是 2 个成员的结构不会被优化掉。

虽然 gcc 不会删除这种特殊情况下的构造,但它可能会在以下情况下进行更积极的优化:struct成员本身被宣布volatile,而不是struct其本身在构造时:

typedef struct {
    volatile uint32_t a, b;
} vol2;

void volatile_def2()
{
    vol2 temp = {1, 2};
    vol2 temp2 = {1, 2};
    temp.a = temp2.a;
    temp.a = temp2.a;
}

简单地编译成一个简单的ret.

虽然删除这些几乎不可能通过任何合理过程观察到的商店似乎完全“合理”,但我的印象是,在标准中volatile假设加载和存储是一部分可观察的行为程序(除了调用 IO 函数),完全停止。这意味着它们不会被“好像”删除,因为根据定义它会改变可观察的行为的程序。

是我错了,还是 clang 违反了这里的规则?也许建造被排除在以下情况之外:volatile必须假设有副作用吗?


从标准的角度来看,不要求实现记录有关对象如何物理存储在内存中的任何信息。即使实现记录了使用类型指针的行为unsigned char*为了访问某种类型的对象,将允许实现以其他方式物理存储数据,然后让基于字符的读取和写入的代码适当地调整行为。

如果执行平台指定了抽象机对象与 CPU 所见的存储之间的关系,并定义了访问某些 CPU 地址可能触发编译器不知道的副作用的方式,则适合低级编程的高质量编译器在该平台上应该生成代码,其中的行为volatile-合格的对象与该规范一致。该标准并不试图强制所有实现都适合低级编程(或任何其他特定目的)。

如果自动变量的地址从未暴露给外部代码,则volatile限定符只需要有两个效果:

  1. If setjmp在函数内调用时,编译器必须采取一切必要措施来确保longjmp不会破坏任何人的价值观volatile- 限定对象,即使它们是在setjmp and longjmp。如果没有限定符,则写入之间的对象的值setjmp and longjmp当a时将变得不确定longjmp被执行。

  2. 允许编译器假定任何没有副作用的循环将运行完成的规则​​不适用于在循环内访问易失性对象的情况,无论实现是否定义此类访问的任何方式是可以观察到的。

除了这些情况之外,as-if 规则将允许编译器实现volatile抽象机中的限定符与物理机无关。

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

优化易失性堆栈变量的存储/构造是否合法? 的相关文章

  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • ASP.NET MVC 中的经典 ASP (C#)

    我有一个应用程序想要 最终 转换为 ASP NET MVC 我想要进行全面的服务升级 到 ASP NET 但想要使用当前的 ASP 内容来运行当前的功能 这样我就可以在对新框架进行增量升级的同时升级小部分 该站点严重依赖于不太成熟的 VB6
  • 向 ExpandoObject 添加方法时,“关键字 'this' 在静态属性、静态方法或静态字段初始值设定项中无效”

    我尝试向 ExpandoObject 添加一个动态方法 该方法将返回属性 动态添加 给它 但它总是给我错误 我在这里做错了什么吗 using System using System Collections Generic using Sys
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 32 位应用程序的特征最大矩阵大小

    所以 我正在寻找Eigen http eigen tuxfamily org index php title Main Page当我尝试声明大于 10000x10000 的矩阵时 包崩溃 我需要声明一个像这样的矩阵 可靠地大约有 13000
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 为什么我不应该对不是由 malloc() 分配的变量调用 free() ?

    我在某处读到 使用它是灾难性的free删除不是通过调用创建的对象malloc 这是真的 为什么 这是未定义的行为 永远不要尝试它 让我们看看当您尝试时会发生什么free 自动变量 堆管理器必须推断出如何获取内存块的所有权 为此 它要么必须使
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • 为什么拆箱枚举会产生奇怪的结果?

    考虑以下 Object box 5 int int int box int 5 int nullableInt box as int nullableInt 5 StringComparison enum StringComparison
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐

  • 焦点/按下时 TextView 颜色发生变化

    我有一些 ui 小部件 包括可点击的relativelayout 内的textview 我的问题是 尽管我已正确设置 textview 颜色属性 但当relativelayout 获得焦点时 textview 文本颜色不会改变 有没有什么简
  • Xcode 构建失败,致命错误:找不到模块“firebase_auth”@import firebase_auth;

    Doctor summary to see all details run flutter doctor v Flutter Channel stable v1 17 4 on Mac OS X 10 15 5 19F101 locale
  • 如何测试Nestjs拦截器?

    我找不到任何关于如何在 NestJS 中测试拦截器的解释 这个简单的示例拦截 POST 查询以将属性添加到正文中提供的示例模型中 Injectable export class SubscriberInterceptor implement
  • 我可以知道提交的修订号吗?

    我可以通过 svn info 等命令查看 svn 中的修订号 但在 git 中我只能看到 sha 对象名称 有什么方法可以知道已提交了多少修订 git 描述将是获取此类信息的最接近的方法 如本中所建议的其他问题 torvalds g5 gi
  • 无法使用 AVCaptureAudioDataOutputSampleDelegate 播放从语音录制的音频

    我已经用谷歌搜索和研究了好几天 但我似乎无法让它发挥作用 而且我在互联网上找不到任何解决方案 我正在尝试使用麦克风捕获我的声音 然后通过扬声器播放 这是我的代码 class ViewController UIViewController A
  • 您不应在 之外使用

    我正在尝试在示例应用程序中设置反应路由器 但出现以下错误 You should not use outside a
  • 时间:2019-05-17 标签:c#sqlwhattodispose

    我有下面的代码来从存储过程中查询记录 但担心我可能不会处理我需要的内容 或者无论如何在垃圾收集器不久之后清除该对象时正在处理 我是否需要处置 SqlDataReader 因为它位于 try catch 块内 我是否需要同时运行 cmd Di
  • Swift 中不同类型的多维数组

    当所有维度都具有相同类型时 我可以轻松地在 Swift 中编写多维数组 例如 var totalTime Int 如何使第一个维度为 String 第二个维度为 Int 我建议改用元组数组 你想要什么could可以使用 Any 类型的数组来
  • 如何寻找有用的红宝石

    有哪些寻找有用红宝石的好网站 敏捷网络开发列出插件 虽然不是 ruby gems 我不知道为什么 并允许人们对它们进行评分 红宝石工具箱按类别列出宝石并比较它们的受欢迎程度 Rubygems有一个搜索框 堆栈溢出对最有用的 Rails 插件
  • (重新)将 std::algorithms 与非标准容器一起使用

    我有一个 列 容器类型 struct MyColumnType Data Each row represents a member of an object vector
  • 如何向整数添加尾随零

    我有一个正整数变量 其值可以在 0 到 999 之间 然后将该整数传递给软件 要传递到该软件中 整数应始终为 3 位数字 但问题是 它应该有尾随零 例如 1 should be passed as 100 19 should be pass
  • 在 jPlayer 中使用来自 PHP 的 JSON 动态填充播放列表

    我有一个 PHP 可以在目录中创建 mp3 文件的 JSON 数组 PHP 的 JSON 数组输出为 title Kalimba mp3 path to mydirectory Kalimba mp3 title Maid with the
  • 在 SQL“IN”子句中使用元组

    我有一个包含字段 group id 和 group type 的表 我想查询该表中具有任何元组的所有记录 group id 团体类型 来自元组列表 例如 我希望能够执行以下操作 SELECT FROM mytable WHERE group
  • 学完基础PHP后做什么? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我已经学习了非常基本的 PHP 我认为是这样 琳达教程 在那之后 我觉得我对这种语言有了一定的掌握 我的志向是成为一名网络开发人员 经过一番谷歌搜索后 我计划通过使用 PHPSC
  • 如何在 Xamarin 中添加计时器?

    所以我需要一个计时器从 60 秒开始倒计时 我是 Xamarin 新手 不知道它接受什么 它将用于Android 关于如何开始有什么建议吗 你能用吗System Timers Timer 您可以使用 System Threading Tim
  • Python3 ImportError:没有名为“_tkinter”的模块[重复]

    这个问题在这里已经有答案了 在我的 Linux Mint 18 上 我尝试在 3 5 2 旁边安装 Python 3 6 1 使用这些命令 wget https www python org ftp python 3 6 1 Python
  • 在 JDK 9 上使用 Ignite

    我在 JDK 9 上使用 Ignite 时遇到问题 我有以下最小测试用例 package no ovstetun ignite import org apache ignite spi discovery tcp TcpDiscoveryS
  • 什么是 Jdbc 类型 5 驱动程序

    什么是 JDBC 类型 5 驱动程序 这样的司机有什么好处呢 我可以获得有关 5 类驱动程序的任何链接 教程吗 目前有四种类型的 JDBC 驱动程序 看 JDBC 技术驱动程序的类型 有一些猜测关于下一个类型会是什么样子
  • Swift 4 Codable - API 有时提供 Int,有时提供 String

    我现在正在运行 Codables 但 API 有一些字符串条目 有时可能有一个Int的价值0如果它们是空的 我在这里搜索并发现了这个 Swift 4 Codable Bool 或 String 值但我无法让它运行 我的结构 struct c
  • 优化易失性堆栈变量的存储/构造是否合法?

    我注意到 clang 和 gcc 优化了易失性的构造或分配struct在某些情况下 在堆栈上声明 例如 以下代码 struct nonvol2 uint32 t a b void volatile struct2 volatile nonv