当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?
假设我正在开发一个名为 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 的类型,其中包括:
处理这种情况的教科书方法是 pimpl 习惯用法:libModern 将提供一个包装类型,该类型内部有一个指向遗留数据的指针。然而,这在这里是不可能的,因为 libModern 无法分配动态内存。一般来说,其目标不是增加大量开销。
因此,libModern 定义了自己的类型,这些类型与遗留类型布局兼容,但具有更好的接口。在此示例中,它使用强标志enum而不是普通uint32_t标志:
enum class ModernFlags : …Run Code Online (Sandbox Code Playgroud)