是严格别名规则真的"双行道"? [英] Is the strict aliasing rule really a "two-way street"?

查看:198
本文介绍了是严格别名规则真的"双行道"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在<一个href=\"http://stackoverflow.com/questions/24597582/copy-value-of-long-long-int-to-char-array-dynamically/24598190?noredirect=1#comment38110777_24597582\">these评论用户@Deduplicator坚持严格走样规则允许通过一个不兼容的类型访问如果任的 的混叠或混叠指针指向到字符的类型(合格或不合格,签署或无符号的char * )。所以,他的说法基本上是两个

In these comments user @Deduplicator insists that the strict aliasing rule permits access through an incompatible type if either of the aliased or the aliasing pointer is a pointer-to-character type (qualified or unqualified, signed or unsigned char *). So, his assertion is basically that both

long long foo;
char *p = (char *)&foo;
*p; // just in order to dereference 'p'

char foo[sizeof(long long)];
long long *p = (long long *)&foo[0];
*p; // just in order to dereference 'p'

是合乎规范的,并定义的行为。

are conforming and have defined behavior.

在我读,但是,它的只有第一个形式,是有效的,也就是说,当混叠的指针指向到字符;然而,可以这样做,在另一个方向上,也就是即当别名指针指向一个不兼容的类型(而不是字符类型除外),在别名的指针是一个的char *

In my read, however, it is only the first form that is valid, that is, when the aliasing pointer is a pointer-to-char; however, one can't do that in the other direction, i. e. when the aliasing pointer points to an incompatible type (other than a character type), the aliased pointer being a char *.

所以,在第二个片段上方将有不确定的行为。

有什么情况?它是否正确?为了记录在案,我已经阅读这个问题,回答和那里的接受的答案明确指出,

What's the case? Is this correct? For the record, I have already read this question and answer, and there the accepted answer explicitly states that

该规则允许的char * 例外。它总是假设的char * 别名等类型。 然而,这是行不通的另一种方式,没有假设,你的结构别名字符的缓冲区。

The rules allow an exception for char *. It's always assumed that char * aliases other types. However this won't work the other way, there's no assumption that your struct aliases a buffer of chars.

(重点煤矿)

推荐答案

您是否正确地说,这是无效的。正如你所引述的(所以我不得重新报价这里)保证有效铸只能从其他任何类型为char *。

You are correct to say that this is not valid. As you yourself have quoted (so I shall not re-quote here) the guaranteed valid cast is only from any other type to char*.

另一种形式是对确实标准,导致不确定的行为。但是作为一个小的奖金,让我们讨论这个标准有点落后了。

The other form is indeed against standard and causes undefined behaviour. However as a little bonus let us discuss a little behind this standard.

个字符,每一个显著的架构是允许完全对齐访问的唯一类型,这是由于其在任何字节工作读取字节指令,否则他们将几乎毫无用处。这意味着间接读为char永远是每一个我所知道的CPU上有效。

Chars, on every significant architecture is the only type that allows completely unaligned access, this is due to the read byte instructions having to work on any byte, otherwise they would be all but useless. This means that an indirect read to a char will always be valid on every CPU I know of.

不过这周围的其他方式将不适用,你不能,除非指针对准8个字节大多数拱门读uint64_t中。

However the other way around this will not apply, you cannot read a uint64_t unless the pointer is aligned to 8 bytes on most arches.

然而,有一个非常普遍的编译器扩展允许您从炭投正确对准指针其它类型和访问它们,然而,这是非标准的。还注意到,如果将一指针的任何类型的指针到char然后将它转换回所得指针被保证是等于原始对象。因此,这是确定的:

However, there is a very common compiler extension allowing you to cast properly aligned pointers from char to other types and access them, however this is non-standard. Also note, if you cast a pointer to any type to a pointer to char and then cast it back the resultant pointer is guaranteed to be equal to the original object. Therefore this is ok:

struct x *mystruct = MakeAMyStruct();
char * foo = (char *)mystruct;
struct x *mystruct2 = (struct mystruct *)foo;

和mystruct2将等于MYSTRUCT。这也保证了结构正确地为它的需求相一致。

And mystruct2 will equal mystruct. This also guarantees the struct is properly aligned for it's needs.

所以基本上,如果你想要一个字符指针和指向另一种类型,总是声明指向其他类型的再转换为字符。甚至更好的使用工会,这是他们所基本上是...

So basically, if you want a pointer to char and a pointer to another type, always declare the pointer to the other type then cast to char. Or even better use a union, that is what they are basically for...

请注意,还有一个显着的例外,不过规则。使用的malloc一些老的实现返回一个char *。该指针总是保证被强制转换为任何类型的成功没有打破别名规则。

Note, there is a notable exception to the rule however. Some old implementations of malloc used to return a char*. This pointer is always guaranteed to be castable to any type successfully without breaking aliasing rules.

这篇关于是严格别名规则真的&QUOT;双行道&QUOT;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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