是否从size_t或uintptr_t来回转换指针会破坏严格的别名?
我建议更改一个库,其公共API目前看起来像这样:
typedef size_t enh; /* handle */ int en_open(enh *handle) { struct internal *e = malloc(...); *handle = (enh)e; return 0; } int en_start(enh handle) { struct internal *e = (struct internal*)handle; return do_something(e); }
这种用法,来回于size_t
破坏严格的别名吗?
为了记录,我建议在公共API中使用struct internal
的典型opaque前向声明, 如此Programmers.SE关于相同代码的问题所示。
别名是用于访问相同字节的两个不同类型的指针。 在您的代码中不是这种情况。 当您访问句柄后面的数据成员时,总是通过struct internal*
类型的指针来完成。 所以这里没有坏处。
代码中唯一值得怀疑的是,你使用size_t
来传递指针。 Afaik,标准并不保证您可以安全地将指针强制转换为size_t
并返回,即使任何理智的实现都允许它。 正确的整数类型选择是uintptr_t
,但你甚至不需要:
我想,你应该在界面中使用一个不透明的指针。 我,只是把声明
typedef struct internal internal;
进入你的公共标题并保持相应的
struct internal { ... }
私人(当然,用一个合理的公共名称替换internal
)。 然后,公共函数可以简单地声明为:
int en_open(internal** outHandle); int en_close(internal* handle);
这样,您就可以在客户端代码中获得完美的类型检查,并避免任何强制转换。