是否从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); 

这样,您就可以在客户端代码中获得完美的类型检查,并避免任何强制转换。

Interesting Posts