【问题标题】:Well definedness of C++ programs hiding pointers隐藏指针的 C++ 程序的明确定义
【发布时间】:2025-12-12 05:15:02
【问题描述】:

According to Wikipedia:

C++11 定义了指针值“安全”的条件 从其他值派生“。实现可以指定它 在“严格的指针安全”下运行,在这种情况下,指针 不按这些规则派生的可能会失效。

当我阅读它时,您可以获得实现所使用的安全模型,但是对于编译器来说这是固定的(可能是带有命令行开关的变量)。

假设我有隐藏指针的代码,这样的代码肯定不会在垃圾收集器上使用天真的螺栓运行。然而收集器(比如我自己的)和 Boehm 提供了在某些对象中查找指针的钩子。

我特别在想 JudyArrays。这些是必然隐藏密钥的数字尝试。我的问题基本上是使用这样的数据结构是否会导致 C++11 中未定义程序的行为。

我希望不会(因为 Judy Arrays 的性能优于其他所有产品)。碰巧也是……我正在使用它们来实现一个垃圾收集器。然而,我很担心,因为“最低要求”根本不起作用,并且在最初关于 C++ 一致性模型的辩论(英国和澳大利亚)中遭到强烈反对。参数要求更好。但是C++11 GC相关的文字似乎有点两者兼而有之所以我很困惑!

【问题讨论】:

    标签: c++ c++11 garbage-collection


    【解决方案1】:

    它的实现定义了一个实现是提供宽松的指针安全(您似乎想要的)还是严格的指针安全(指针仅在safely derived 时保持有效)。正如您所暗示的,您可以致电get_pointer_safety 来了解政策是什么,但该标准没有提供指定/更改政策的方法。

    但是,您可以回避这个问题。如果您可以在隐藏指针之前调用declare_reachable(传递该指针值),则它在匹配调用undeclare_reachable 之前一直有效(这里“匹配”表示调用嵌套)。

    【讨论】:

    • 在这种情况下我可以做到,但它可能会非常昂贵:跟踪它的最快方法无疑是使用 Judy Array,而这正是我所使用的 Judy Array using 被用于。假设它不是 nop,充其量这会使访问时间加倍,并且(更有可能)C++ 收集器将使用劣质数据结构。
    • @Yttrill:鉴于您正在实施 GC,也许至少考虑一下它是否真的不应该被视为/作为实施的一部分是合理的。在这种情况下,也许您将实现 declare_reachable 以将指针添加到您的 Judy 数组。
    • 我的猜测是实际的编译器会使用系统 GC 和命令行控制的指针安全策略。我认为使用 Boehm 收集器的现有 libgc 实现可以与 Judy 一起使用,但你必须告诉收集器。但是,如果您这样做,您会希望程序在没有 declare_reachable 的情况下工作,但从技术上讲,该行为可能是未定义的。
    • 好吧,GC 是“实现”的一部分,但我没有实现 C++,而是一种编译器生成 C++ 的语言。所以我不会“实现”declare_reachable,我必须考虑生成的代码是否需要调用它。
    • @Yttrill:对于这样的情况,您的语言的 GC 堆会有内存块。您将使用new 分配这些块,并保留指向它们的指针(至少是半永久的),以便整个块保持有效。您的 GC 将在那里处理较小的部分,但无论在块内隐藏其他指针,整个块都将保持有效。