从 size_t 或 uintptr_t 来回投射指针是否会破坏严格的别名? [英] Does casting a pointer back and forth from size_t or uintptr_t break strict aliasing?

查看:26
本文介绍了从 size_t 或 uintptr_t 来回投射指针是否会破坏严格的别名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我提议更改一个库,其公共 API 目前如下所示:

I'm proposing a change to a library whose public API currently looks like this:

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 是否打破了严格的别名?

Does this usage, casting back and forth to size_t break strict aliasing?

作为记录,我提议在公共 API 中对 struct internal 进行典型的不透明前向声明,如 关于相同代码的这个 Programmers.SE 问题.

For the record, I'm proposing a typical opaque forward declaration of struct internal in the public API, as shown on this Programmers.SE question about the same code.

推荐答案

别名是关于两个不同类型的指针用于访问相同的字节.在您的代码中并非如此.当您访问句柄后面的数据成员时,您总是通过 struct internal* 类型的指针来进行.所以这里没有坏处.

Aliasing is about two pointers of different type being used to access the same bytes. This is not the case in your code. When you access the data members behind the handle, you always do it via a pointer of type struct internal*. So no harm here.

您的代码中唯一有问题的是,您正在使用 size_t 来传递指针.Afaik,该标准不保证您可以安全地将指针转换为 size_t 并返回,即使任何理智的实现都允许它.正确的整数类型选择是 uintptr_t,但您甚至不需要:

The only questionable thing in your code is, that you are using size_t to pass the pointer. Afaik, the standard does not guarantee that you can safely cast a pointer to size_t and back, even though any sane implementation will allow it. The correct integer type choice would be uintptr_t, but you don't even need that:

我认为,你应该在界面中使用一个不透明的指针.即,只需放置声明

I think, you should just use an opaque pointer in the interface. I. e., just put the declaration

typedef struct internal internal;

进入您的公共标题并保留相应的

into your public header and keep the corresponding

struct internal {
    ...
}

private(当然,用一个合理的公共名称替换 internal).公共函数可以简单地声明为:

private (replacing internal with a sensible public name, of course). The public functions can then simply be declared as:

int en_open(internal** outHandle);
int en_close(internal* handle);

这样,您就可以在客户端代码中进行完美的类型检查,而无需进行任何强制转换.

That way, you get perfect type checking in the client code, and avoid the need for any casts.

这篇关于从 size_t 或 uintptr_t 来回投射指针是否会破坏严格的别名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆