【问题标题】:Strict aliasing rule violation严格的别名规则违规
【发布时间】:2017-02-25 11:46:43
【问题描述】:

在这个 link from the isocpp.org faq 提供的示例中,正在构造一个 Fred 对象,并将新位置放置在为另一个对象分配的缓冲区中,即为

char memory[sizeof(Fred)]

据我所知,严格的别名规则允许我们做相反的事情,即对于任何类型的对象,我们可以有一个 char* 指向它,我们可以取消引用该指针并根据需要使用它。

但在本例中,情况正好相反。我错过了什么?

【问题讨论】:

  • 让我投反对票的问题有什么问题?
  • 有太多笨蛋不在乎他们。我给了+1。当你卡住时,不要放弃跟上提问的步伐。该网站用于学习。
  • 这将改善问题,以在问题中显示您所询问的代码,而不是具有可能随时间变化的外部链接,并且有几个代码示例。

标签: c++ strict-aliasing


【解决方案1】:

Placement-new 创建一个新对象。它不会给旧对象起别名。当placement-new 执行时,旧对象(本例中的char 数组)被认为停止存在。

在placement-new 之前,有char 对象填充的存储空间。在placement-new之后,有一个Fred对象的存储空间。

由于没有混叠,所以不存在严格混叠问题。

【讨论】:

  • 我相信在这个例子中放置 new 之后使用 memory 是未定义的行为。那是对的吗? place呢?
  • 我认为在那之后使用内存不会是未定义的。由于上面发布的 sn-p StoryTeller。所以@MM我想我明白了。有一件事,如果有人现在有一个指向内存的指针 char*,在这个函数之外并且知道在那里,存储了一个 Fred 类型的对象。他想将它重新解释为 Fred*。他被允许这样做的原因是因为link中有5个。但随后要取消引用,他需要从该链接下方的 Type aliasing 中的一个项目符号来证明它是正确的。正确的?如果是,是哪个?
  • 或者即使在这种情况下,这也不算作别名?
  • @esam 此代码中没有未定义的行为。
  • @user183833 "aliasing" 使用一种类型的左值来访问不同类型的对象。在本示例中不会发生这种情况。在您的情况下(如果我理解正确),其他人可以使用 Fredchar 访问 Fred 对象。 (使用char 会产生别名,但允许使用 char 对其他对象进行别名)。
【解决方案2】:

严格的别名规则没有提到必须将Fred* 强制转换为char*。只有char*Fred* 类型的变量可以指向同一个对象,并用于访问它。

引用[basic.lval] paragraph 8

如果程序尝试通过以下方式访问对象的存储值 行为是以下类型之一以外的泛左值 未定义:

  • 对象的动态类型,

    [..]

  • char 或 unsigned char 类型。

【讨论】:

  • 是的,但我理解的例子中发生的情况恰恰相反。对象的值是从类型 Fred 访问的。您发布的这个 sn-p 说的是另一个方向,即从 char 类型访问的 Fred 对象。
  • 这里的“动态类型”也是继承的意思吗?
  • @user183833 sn-p 不会强加任何一个方向。它们在这种情况下都是有效的。是的,它在继承方面是动态的。
猜你喜欢
  • 1970-01-01
  • 2015-10-15
  • 2020-04-11
  • 2015-01-16
  • 1970-01-01
  • 2016-02-24
  • 2021-10-21
相关资源
最近更新 更多