是否从size_t或uintptr_t来回转换指针会破坏严格的别名?

时间:2015-08-28 21:02:16

标签: c api-design strict-aliasing

我建议更改其公共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所示。

1 个答案:

答案 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);

这样,您就可以在客户端代码中获得完美的类型检查,并且无需任何演员表。