相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

高效的类型双关,没有未定义的行为

假设我正在开发一个名为 libModern 的库。该库使用称为 libLegacy 的遗留 C 库作为实现策略。libLegacy 的界面如下所示:

typedef uint32_t LegacyFlags;

struct LegacyFoo {
    uint32_t x;
    uint32_t y;
    LegacyFlags flags;
    // more data
};

struct LegacyBar {
    LegacyFoo foo;
    float a;
    // more data
};

void legacy_input(LegacyBar const* s); // Does something with s
void legacy_output(LegacyBar* s); // Stores data in s
Run Code Online (Sandbox Code Playgroud)

出于各种原因,libModern 不应该向用户公开 libLegacy 的类型,其中包括:

  • libLegacy 是一个不应泄露的实现细节。libModern 的未来版本可能会选择使用另一个库而不是 libLegacy。
  • libLegacy 使用难以使用、容易误用的类型,这些类型不应成为任何面向用户的 API 的一部分。

处理这种情况的教科书方法是 pimpl 习惯用法:libModern 将提供一个包装类型,该类型内部有一个指向遗留数据的指针。然而,这在这里是不可能的,因为 libModern 无法分配动态内存。一般来说,其目标不是增加大量开销。

因此,libModern 定义了自己的类型,这些类型与遗留类型布局兼容,但具有更好的接口。在此示例中,它使用强标志enum而不是普通uint32_t标志:

enum class ModernFlags : …
Run Code Online (Sandbox Code Playgroud)

c++ gcc language-lawyer type-punning c++20

8
推荐指数
1
解决办法
669
查看次数