我建议更改其公共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
的典型不透明前向声明,如this Programmers.SE question about the same code所示。
答案 0 :(得分:6)
别名是用于访问相同字节的两个不同类型的指针。在您的代码中不是这种情况。当您访问句柄后面的数据成员时,您始终通过类型为struct internal*
的指针来执行此操作。所以这里没有坏处。
代码中唯一值得怀疑的是,您使用size_t
来传递指针。 Afaik,标准并不能保证您可以安全地将指针转换为size_t
并返回,即使任何理智的实现都允许它。正确的整数类型选择是uintptr_t
,但您甚至不需要:
我认为,您应该在界面中使用不透明指针。 I. e。,只需填写声明
typedef struct internal internal;
进入你的公共标题并保留相应的
struct internal {
...
}
私人(当然,用合理的公共名称替换internal
)。然后可以简单地将公共函数声明为:
int en_open(internal** outHandle);
int en_close(internal* handle);
这样,您就可以在客户端代码中获得完美的类型检查,并且无需任何演员表。