【问题标题】:Is it safe to reinterpret_cast<bool*> zeroed out memory?reinterpret_cast<bool*> 清零内存是否安全?
【发布时间】:2016-04-01 03:01:10
【问题描述】:

上下文:

我有一块内存通过shm_open 在两个进程之间共享。我保证在ftruncateing 和mmaping 之后,整个块都有00000... 的位模式。我需要在两个进程之间共享一个布尔值。

一个更具体的问题:

在合理的 POSIX 系统上是否保证以下内容正常(断言不会失败并且 UB 不会发生)?

void *my_shared_memory_region = calloc(1024, 1);
bool *my_bool = reinterpret_cast<bool*>(my_shared_memory_region);
assert(*my_bool == false);

我认为bool 中的实际值存在一些限制,所以我不确定。我认为这个问题与this one 不同,因为reinterpret_cast 不会进行与C 样式转换相同的转换。

【问题讨论】:

  • 从技术上讲,除了使用placement-new 创建新对象之外,在malloc 空间中执行任何操作都是C++ 中未定义的行为。我个人认为这更像是标准中的一个缺陷,并且希望您的代码能够正常工作。顺便说一句,你可以在这里使用static_cast
  • @M.M:哎呀,谢谢!
  • @M.M.:实际上,只要获得足够大小和正确对齐的存储空间,就存在一个简单初始化的对象(包括bool)。也就是说,您必须考虑它包含一个不确定的值,直到您使用相同类型的左值写入它(严格的别名规则)。
  • @PatrickCollins:请注意,您在指针上使用reinterpret_cast,而不是指向的数据。所以转换和演员风格不是问题。
  • 为什么不使用unsigned char?它似乎只是为了这样的事情而存在。

标签: c++ pointers casting boolean


【解决方案1】:

核心问题 - 即使内存全为零,是否像从正确初始化的 bool 中读取一样有效 - 与 this question 相同。

长话短说:未定义的行为适用于通用系统,但不能保证可移植。允许特定实现记录标准未定义的情况下的行为,因此值得对您关心的特定平台/编译器进行一些研究。

【讨论】:

  • 真的是 undefined 行为,还是只是 unspecified 的值?
  • 值本身最好被称为 uninitialised,因为它没有经过适当的 C++ 初始化,从而导致读取 - bool *my_bool = reinterpret_cast&lt;bool*&gt;(my_shared_memory_region); - 未定义的行为。有趣的是,C++11 标准中的脚注 48) 费力描述了一种可能表现出未定义行为的方式:“以本国际标准描述为“未定义”的方式使用 bool 值,例如检查未初始化的自动对象的值,可能会导致其表现得好像既不是true 也不是false。"
  • 链接的问题使用术语“未指定”(“此操作不会使原本正确的程序不正确,但不能保证在所有系统上返回相同的值”)而不是“ undefined'(“鼻恶魔,符合标准的实现可能会选择让你的 CPU 着火,等等”)。你的例子很有说服力,但那里描述的语言强烈表明这不是鼻恶魔领域。
  • @PatrickCollins:我认为链接答案中的“未指定”是常见的英语用法,而不是标准语。如果您考虑答案的逻辑,它基于 boost 文档声称 C11 有一些保证,但发现的唯一证据是 C99 缺陷报告。 [这个答案]stackoverflow.com/a/11139915/410767) 直接解决了这个问题,我的解读是 bool 可能有填充位,并且它们的合法内容/导入不受标准规定。这留下了陷阱表示的可能性。
猜你喜欢
  • 2015-08-21
  • 2020-11-05
  • 2014-03-12
  • 2017-02-19
  • 1970-01-01
  • 2010-12-09
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多