问题标签 [type-punning]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
546 浏览

c - 分配和获取联合值,类型双关语

我有工会,好吧。
这个联合在一个结构内,并且那个联合是未命名的(类似的东西)。

我将像这样初始化我的结构。

好的,我知道这项工作是因为,根据定义,当我使用这种初始化时,将使用联合的第一个字段。
所以问题是:
如果我这样写初始化会发生什么?

当我尝试检索浮点值后,我会得到正确的值吗?

这会显示正确的东西吗?
这适用于每种类型吗?甚至指向功能一的指针?

我问这个是因为根据定义,初始化将值放在我的联合的第一个字段中,所以,如果 float 大于 int 会有问题吗?我不知道这一点,所以,我知道指向函数的指针有时可能比 int 大,所以我需要用指向函数的指针作为第一个成员编写我的联合?

我读到 GCC 支持类型双关,甚至 linux 内核也使用类型双关。所以我只担心我是否可以在该结构上使用这种初始化,然后获得正确的值。

0 投票
8 回答
9291 浏览

c++ - 将 float 类型转换为 int 的正确方法是什么,反之亦然?

下面的代码通过一些位黑客来执行快速的平方根逆运算。该算法可能是由 Silicon Graphics 在 1990 年代早期开发的,它也出现在 Quake 3 中。 更多信息

但是,我从 GCC C++ 编译器收到以下警告:取消引用类型双关指针将破坏严格别名规则

我应该使用static_cast,reinterpret_cast还是dynamic_cast在这种情况下使用?

0 投票
3 回答
236 浏览

c++ - 类型双关语 - 编译器如何决定使用什么类型?

我在这里阅读这个关于决定字节顺序的问题,第一个答案让我有些困惑。

用于决定大字节序的代码如下:

我的问题是这里的编译器如何决定该十六进制数字数组使用什么类型?因为从技术上讲,它同样适用于 thatuint32_t或 that char[4]

为什么不直接将其存储在 中char[4]并跳过union

这里有一些union我看不到的优势吗?我知道这被称为类型双关语,但在这里我看不到它的优势。

0 投票
3 回答
2556 浏览

c++ - C++ 中的共享内存缓冲区不违反严格的别名规则

我在不违反 C99 严格的别名规则的情况下努力实现共享内存缓冲区。

假设我有一些代码可以处理一些数据并且需要一些“临时”内存来操作。我可以这样写:

然后我有另一个函数可以做一些其他的事情,也需要一个暂存缓冲区:

问题是 foo() 和 bar() 在操作过程中可能会被多次调用,并且在整个地方进行堆分配可能在性能和内存碎片方面非常糟糕。一个明显的解决方案是分配一个适当大小的公共共享内存缓冲区,然后将其作为参数传递给 foo() 和 bar(),BYOB 样式:


我想我现在有两个问题:
- 如何实现不违反别名规则的共享公共暂存内存缓冲区?
- 尽管上面的代码确实违反了严格的别名规则,但别名并没有“伤害”。因此,任何理智的编译器都可以生成(优化的)代码,但仍然会给我带来麻烦吗?

谢谢

0 投票
4 回答
672 浏览

c++ - C/C++ 严格别名、对象生命周期和现代编译器

我对 C++ 严格别名规则及其可能的影响感到困惑。考虑以下代码:

查看 C++ 规范,第 3.10.10 节,从技术上讲,给定的代码似乎都没有违反那里给出的“别名规则”:

如果程序试图通过以下类型之一以外的左值访问对象的存储值,则行为未定义:
... 合格访问器类型列表 ...

  • *f = 1.0f;不会违反规则,因为无法访问存储的值,即我只是通过指针写入内存。我不是从记忆中读取或试图在这里解释一个值。
  • 该行int32_t b = a;不违反规则,因为我是通过其原始类型访问的。
  • float g = *f;出于同样的原因,这条线并没有违反规则。

另一个线程中,成员 CortAmmon 实际上在响应中提出了相同的观点,并补充说,通过写入活动对象产生的任何可能的未定义行为,如 中 *f = 1.0f;,将由标准的“对象生命周期”定义(似乎是对于 POD 类型来说微不足道)。

但是:互联网上有大量证据表明上述代码将在现代编译器上产生 UB。例如,请参见此处此处
大多数情况下的论点是编译器可以自由考虑&a并且f不会相互混淆,因此可以自由地重新调度指令。

现在最大的问题是,这种编译器行为是否实际上是对标准的“过度解释”。
该标准唯一一次专门讨论“别名”是在 3.10.10 的脚注中,其中清楚地表明这些是管理别名的规则。
正如我之前提到的,我没有看到任何上述代码违反标准,但很多人(可能还有编译器人员)会认为它是非法的。

我真的很感激这里的一些澄清。

小更新:
正如成员 BenVoigt 正确指出的那样,在某些平台上int32_t可能无法对齐,float因此给定的代码可能违反了“存储足够对齐和大小”的规则。我想说的int32_t是,在大多数平台上故意选择与此一致,float并且此问题的假设是类型确实对齐。

小更新#2:
正如几位成员所指出的,这条线int32_t b = a;可能违反了标准,尽管不是绝对肯定的。我同意这一观点,并且不改变问题的任何方面,请读者从我上面的声明中排除该行,即没有任何代码违反标准。

0 投票
3 回答
316 浏览

c - 通过类型双关语进行 C 继承,没有包含?

我现在需要在 C 中获得一些面向对象的特性,特别是继承。幸运的是,有一些关于堆栈溢出的很好的参考资料,特别是C 中的半继承:这个片段如何工作?和 C 中的这个面向对象。这个想法是在派生类中包含一个基类的实例并对其进行类型转换,如下所示:

这很好,但是对于深度继承树来说它变得很麻烦——我将拥有大约 5-6 个“类”的链,我真的不想一直输入 derived.super.super.super.super.super.super . 我希望我可以将类型转换为前 n 个元素的结构,如下所示:

我已经在 Visual Studio 2012 附带的 C 编译器上对此进行了测试,它可以工作,但我不知道 C 标准是否真的保证它。有没有人可以确定这是否可以?我不想编写大量代码只是为了发现它在如此基本的层面上被破坏了。

0 投票
1 回答
389 浏览

c - 类型双关语与联盟成员访问

按照这个https://stackoverflow.com/a/1812932/1814023 writing one member of union and reading another member is undefined behavior.

按照这个https://stackoverflow.com/a/11640603/1814023 type punning is allowed in C99 / C11

我对这两个帖子有点困惑,哪一个是正确的?在理解类型双关语与访问工会成员方面需要帮助。

谢谢。

0 投票
3 回答
846 浏览

c++ - 非 NULL 保留指针值

如何创建保留的指针值?

上下文是这样的:我一直在考虑如何为动态脚本语言实现数据结构(我不打算实现这个 - 只是想知道它会如何完成)。

字符串可以包含任意字节,包括 NUL。因此,有必要单独存储该值。这需要一个指针(指向数组)和一个数字。第一个技巧是,如果指针为 NULL,则它不可能是有效字符串,因此该数字可用于实际整数。

如果可以创建第二个保留指针值,这可以用来暗示另一个字段现在被用作浮点值。这可以做到吗?

一种想法是 mmap() 一个没有权限的地址,也可以这样做来替换 NULL 指针的使用。

0 投票
2 回答
813 浏览

c++ - 不使用放置 new 返回的指针时的 C++ 严格别名

这可能会导致未定义的行为吗?


char具有严格混叠的特殊规则。如果我使用char而不是 uint8_t它仍然是未定义的行为吗?还有什么变化?

正如成员 DeadMG 指出的那样,reinterpret_cast依赖于实现。如果我改用 C 风格的演员(int32_t*)storage表,会发生什么变化?

0 投票
3 回答
256 浏览

c - 两个联合的算术,未定义的行为?

为什么这只返回 var1 的值而不是总和?如果var1var2添加了相同的分配数据类型,它就可以工作。我认为工会使这成为一个非问题?