std::launder 可用于将对象指针转换为其封闭数组指针吗?

2024-02-09

当前的标准草案(大概是 C++17)说[基本.化合物/4] http://eel.is/c++draft/basic.compound#4:

[ 注意:数组对象及其第一个元素不可进行指针互换,即使它们具有相同的地址。 ——《尾注》

所以指向对象的指针不能reinterpret_castd 获取其封闭的数组指针。

现在,有std::launder, [ptr.launder/1] http://eel.is/c++draft/ptr.launder#1:

template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept;

要求:p表示内存中一个字节的地址A。处于其生命周期内且类型与 T 类似的对象 X 位于地址 A 处。通过结果可访问的所有存储字节都可通过以下方式访问:p(见下文)。

和定义可达的 is in [ptr.launder/3] http://eel.is/c++draft/ptr.launder#3:

备注: 只要该函数的参数值可以在核心常量表达式中使用,就可以在核心常量表达式中使用该函数的调用。如果一个字节的存储空间位于 Y 所占用的存储空间内,则该字节可以通过指向对象 Y 的指针值来访问,该指针值是与 Y 可以进行指针互换的对象,或者是如果 Y 是数组元素,则直接封闭数组对象。如果 T 是函数类型或 cv void,则程序格式错误。

现在乍一看,似乎std::launder因为我强调的部分,所以可以用来进行上述转换。

But. If p指向数组的对象,数组的字节为可达的根据这个定义(即使p不可将指针相互转换为数组指针),就像清洗的结果一样。所以,这个定义似乎没有提到这个问题。

So, can std::launder用于将对象指针转换为其封闭数组指针?


这取决于封闭数组对象是否是一个完整的对象,如果不是,您是否可以通过指向该封闭数组对象的指针有效地访问更多字节(例如,因为它本身是一个数组元素,或者可以与更大的对象进行指针互转换) ,或与数组元素的对象进行指针互换)。 “可达”要求意味着您不能使用launder获取一个指针,该指针允许您访问比源指针值允许的更多字节,但存在未定义的行为。这确保了某些未知代码可能调用的可能性launder不影响编译器的转义分析。

我想一些例子会有所帮助。下面每个例子reinterpret_casts a int*指向 10 数组的第一个元素int变成一个int(*)[10]。由于它们不可进行指针互换,reinterpret_cast不改变指针值,你会得到一个int(*)[10]值为“指向第一个元素(无论数组是什么)的指针”。然后,每个示例尝试通过调用来获取指向整个数组的指针std::launder在强制转换指针上。

int x[10];
auto p = std::launder(reinterpret_cast<int(*)[10]>(&x[0])); 

还行吧;您可以访问的所有元素x通过源指针,以及结果launder不允许您访问任何其他内容。

int x2[2][10];
auto p2 = std::launder(reinterpret_cast<int(*)[10]>(&x2[0][0])); 

这是未定义的。您只能访问以下元素x2[0]通过源指针,但结果(这将是一个指向x2[0])将允许您访问 x2[1],但您无法通过源访问。

struct X { int a[10]; } x3, x4[2]; // assume no padding
auto p3 = std::launder(reinterpret_cast<int(*)[10]>(&x3.a[0])); // OK

还行吧。同样,您不能通过指针访问x3.a您还无法访问的任何字节。

auto p4 = std::launder(reinterpret_cast<int(*)[10]>(&x4[0].a[0])); 

这是(打算)未定义的。你本来可以到达x4[1]从结果来看,因为x4[0].a是指针可相互转换的x4[0],所以指向前者的指针可以是reinterpret_cast产生指向后者的指针,然后可以将其用于指针算术。看https://wg21.link/LWG2859 https://wg21.link/LWG2859.

struct Y { int a[10]; double y; } x5;
auto p3 = std::launder(reinterpret_cast<int(*)[10]>(&x5.a[0])); 

这又是未定义的,因为你本来可以达到x5.y从结果指针(通过reinterpret_cast to a Y*)但源指针不能用于访问它。

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

std::launder 可用于将对象指针转换为其封闭数组指针吗? 的相关文章

  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • Grails 自动重新加载新的控制器操作

    I ve 创建了新的 Grails 2 4 3 项目 created TestController set grails reload enabled true in BuildConfig groovy 运行应用程序grails relo
  • char 数组的问题 = char 数组

    I have char message1 100 char message2 100 当我尝试做的时候message1 message2 我收到错误 分配给类型时不兼容的类型 char 100 从类型 char 我有类似的功能 if sen
  • 用CSS按比例调整图像大小,可能吗?

    有没有办法用 CSS 调整图像大小并保持其比例 容器有固定的宽度和高度 div class container img class theimage src something div 我问的原因是因为布局可以改变 通过类从列表到图标 并且
  • 枚举对继承的支持

    我经常遇到这样的情况 我们创建一个作用于某些枚举的类 但后来我们派生并希望在不更改基类的情况下向枚举添加更多值 我在2009年就看到过这个问题 基枚举类继承 https stackoverflow com questions 644629
  • 使 XStream 忽略一个特定的私有变量

    我目前正在为其编写保存函数的类有一个小问题 我正在使用 XStream com thoughtworks xstream 通过 DOMDriver 将类序列化为 XML 该类看起来像这样 public class World private
  • 如何制作 ToolStripComboBox 来填充 ToolStrip 上的所有可用空间?

    ToolStripComboBox 放置在 ToolStripButton 后面 后面是另一个右对齐的工具条组合框 如何最好地将 ToolStripComboBox 设置为始终调整其长度以填充前后 ToolStripButton 之间的所有
  • Mapbox:仅当注释在屏幕上可见时才添加注释

    我将注释数据存储在 Firebase 的数据库中 我发现只要注释没有自定义视图 我就可以下载 10 000 个注释的数据并将这些注释添加到我的地图中 而不会出现太大的延迟 然而 对于我的应用程序 我需要使用自定义视图 每个注释视图都是由多个
  • 从 pandas 数据框中制作多个饼图(每一行一个)

    我有一个数据框 df 显示与各种业务类别相关的情绪 我的任务是创建饼图 显示每种业务类型的情绪百分比 因此 我需要在 matplotlib 中创建一个函数 该函数读取 Business 列 然后使用数据框中每行的每个情感类别构建饼图 我已经
  • Wear OS 和 iOS 配套应用程序之间的直接通信

    我目前有一个适用于 Android 和 iOS 智能手机的应用程序 我想将其引入 Wear OS 和 Watch OS 由于 Wear OS 智能手表也与 iOS 设备兼容 因此我正在寻找一种在 Watch OS 应用程序和 iOS 应用程
  • 在表格/班级之间共享信息[重复]

    这个问题在这里已经有答案了 我知道标题问题并不独特 并且有很多可用的消息 我打开一个线程的原因是我真的很难根据我的项目来理解这个问题 最近 我尝试启动 WinForm 以从 REST API 获取值 就像在 Form1 上进行开始测试一样
  • 使用 dplyr::percent_rank() 计算组内的百分位数排名

    假设我有以下数据 id grpvar1 grpvar2 value 1 1 3 7 6 2 1 2 4 3 1 5 2 对于每个id 我想计算percent rank of its value在由组合定义的组内grpvar1 and grp
  • Windows ODBC 驱动程序 - 检索的表情符号数据呈现为?

    重复线程注释 我已经针对这个问题提出了类似的问题 通过 ODBC 连接检索的表情符号数据显示为问号 https stackoverflow com questions 58943772 emoji data retrieved via od
  • 聚合函数和其他列

    SQL 查询是否可以返回一些普通列和一些聚合列 like Col A Col B SUM 5 6 7 您应该使用按语句分组 http www w3schools com sql sql groupby asp GROUP BY 语句用于 与
  • 恢复活动时防止多次打开对话框

    在我的 Android 应用程序中 为了询问用户是否要恢复当前游戏 我在主游戏活动中显示一个对话框 显示 您要恢复当前游戏吗 是 否 问题是 如果我在不回答对话的情况下多次恢复此活动 那么我会收到几个对话 一个个对话 这显然不是我的目标 我
  • 如何将 XPath 与 AS3 结合使用并获得仍然引用 XMLDocument 对象的结果?

    我正在将 XML 字符串解析为 XMLDocument 对象 我想使用 XPath 技术搜索特定节点XPathQuery execQuery 此函数返回新的 XML 对象 这意味着我需要将其转换为不同的 XMLDocument 对象并丢失引
  • 升级到 Grails 2.4.4 的问题

    从 Grails 2 4 3 升级到 2 4 4 后 启动 Grails 应用程序时不断出现错误 完整的错误可以在这里阅读 http pastebin com UXQ34JKD http pastebin com UXQ34JKD 2014
  • javascript 的 Jquery 参数替代方案

    我需要转换以下类型字典 key1 value1 key2 value1 value2 to key1 value1 key2 即发布数据表格 我在 chrome 扩展中执行此操作 上面的表单数据字典由以下方式返回 chrome webReq
  • Facebook 无效范围错误

    我用 Rails 应用程序创建了一个 V2 3 的应用程序 4月30日前一切正常 现在我收到此错误 无效范围 offline access publish stream create event 朋友 活动 此消息仅向开发人员显示 用户 如
  • 如何判断虚拟地址在 ARM Linux 内核中是否具有有效映射?

    我想检查是否可以在不引发分段错误的情况下取消引用虚拟地址 我所说的虚拟地址不仅仅是不可信的用户空间地址 我也想检查内核虚拟地址 在 x86 Linux 内核中 可以使用 virt addr valid 函数来检查是否 虚拟地址具有有效的映射
  • std::launder 可用于将对象指针转换为其封闭数组指针吗?

    当前的标准草案 大概是 C 17 说 基本 化合物 4 http eel is c draft basic compound 4 注意 数组对象及其第一个元素不可进行指针互换 即使它们具有相同的地址 尾注 所以指向对象的指针不能reinte