在不违反标准的情况下使用指向结构的指针对数组进行别名

2024-02-11

Reading this http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html我理解,如果结构具有兼容的成员,则可以为结构添加别名(即不违反标准),即给出以下结构:

typedef struct {
    uint32_t a;
    uint32_t b;
} Frizzly;

以下内容会破坏别名规则:

uint32_t foo(uint16_t *i) {
    Frizzly *f = (Frizzly *)i;
    return f->a;
}

但以下情况则不会:

uint32_t foo(uint32_t *i) {
    Frizzly *f = (Frizzly *)i;
    return f->b;
}

因为所讨论的“聚合类型”包含与我们要转换为它的指针兼容的类型,即指向类型的指针uint32_t可以转换为包含类型成员(或成员)的结构uint32_t不违反别名规则。

首先,我的理解正确吗?

其次,结构中(其他)变量的顺序和类型重要吗?说,如果Frizzly定义如下:

typedef struct {
    uint16_t b[2];
    uint32_t a;
}

在第二个示例中进行转换后,b现在由不兼容的内存支持(uint32_t) 类型。强制转换仍然有效(或者更确切地说,通过强制转换的指针访问值)?将更改以下任一元素a改变第一个元素的值i(反之亦然)就像严格别名被禁用一样?

另外,如果上述是有效的,如果我有一个像这样的结构怎么办:

typedef struct {
    void *m;
    uint16_t hooah[4];
} Bar;

如果我是正确的,以下转换将打破别名规则:

void test(char *boo, size_t dee) {
    Bar *bar = (Bar *)(boo + dee);
    do_other_stuff(bar);
}

我可以简单地通过添加一个来使演员阵容有效吗unsigned char成员进入结构体?换句话说,不兼容类型的指针转​​换通常会破坏别名规则,但由于从指针到包含类型成员的结构的转换X变成一个指向X是一个例外,是否可以通过将 X 类型的(可能是虚拟的)成员添加到 Y 中来使从 X 指针到聚合 Y 的任何转换都有效?

(我实际上没有在编译器中测试上述代码片段。)

EDIT:

我知道我的措辞和示例可能相当糟糕,所以我将尝试重新表述这个问题:如果我理解正确,那么只要满足以下条件,指向结构的指针为类型为“X”的元素数组添加别名是合法的该结构包含类型“X”的成员。现在,当取消引用结构体的成员时,该成员是否必须是“X”类型,或者是严格别名规则的例外all结构体的成员无论其类型如何,只要有一个适当类型的成员即可?


根据ISO/IEC9899/TC2 http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf第 6.7.2.1 节第 13 段:

指向结构对象的指针,经过适当转换后,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然

因此,只要将结构指针转换为第一个成员的指针类型,它就不应该违反严格别名(在第 6.5 节第 7 段中指定),也可以通过以下方式访问元素:

聚合或联合类型,其成员中包含上述类型之一(递归地包括子聚合或包含联合的成员)

但这仅适用于另一个方向(通过结构指针访问成员,而不是通过成员指针访问结构)

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

在不违反标准的情况下使用指向结构的指针对数组进行别名 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐