当为char *安全进行严格的指针别名? [英] When is char* safe for strict pointer aliasing?

查看:109
本文介绍了当为char *安全进行严格的指针别名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力,也适用于字符指针理解严格别名规则。

I've been trying to understand the strict aliasing rules as they apply to the char pointer.

<一个href=\"http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html#cast_to_char_pointer\"相对=nofollow>这里这说明:

它总是presumed是一个char *可以指向任何对象的别名。

It is always presumed that a char* may refer to an alias of any object.

好了,所以插座code的情况下,我可以这样做:

Ok so in the context of socket code, I can do this:

struct SocketMsg
{
   int a;
   int b;
};

int main(int argc, char** argv)
{
   // Some code...
   SocketMsg msgToSend;
   msgToSend.a = 0;
   msgToSend.b = 1;
   send(socket, (char*)(&msgToSend), sizeof(msgToSend);
};

不过,再有就是这句话

But then there's this statement

反过来是不正确的。铸造一个char *比一个char *以外的任何类型的指针解引用它通常是违反了严格别名规则。

The converse is not true. Casting a char* to a pointer of any type other than a char* and dereferencing it is usually in violation of the strict aliasing rule.

这是否意味着,当我的recv字符数组,我不能reinter preT投一个struct,当我知道这个消息的结构:

Does this mean that when I recv a char array, I can't reinterpret cast to a struct when I know the structure of the message:

struct SocketMsgToRecv
{
    int a;
    int b;
};

int main()
{
    SocketMsgToRecv* pointerToMsg;
    char msgBuff[100];
    ...
    recv(socket, msgBuff, 100);
    // Ommiting make sure we have a complete message from the stream
    // but lets assume msgBuff[0]  has a complete msg, and lets interpret the msg

    // SAFE!?!?!?
    pointerToMsg = &msgBuff[0];

    printf("Got Msg: a: %i, b: %i", pointerToMsg->a, pointerToMsg->b);
}

将第二个例子不能工作,因为基类型是一个字符数组,我是铸造一个struct?你如何在严格的别名世界处理这种情况?

Will this second example not work because the base type is a char array and I'm casting it to a struct? How do you handle this situation in a strictly aliased world?

推荐答案

重新@Adam罗森菲尔德:工会将实现对齐,只要字符*商开始了在做类似的事情。

Re @Adam Rosenfield: The union will achieve alignment so long as the supplier of the char* started out doing something similar.

这可能是有益的退后一步,搞清楚这是怎么一回事。

It may be useful to stand back and figure out what this is all about.

有混叠规则的基础是一个事实,即编译器可以将不同的简单类型上不同的存储器界限值,以提高在某些情况下,访问与该硬件可能需要这样的对齐,以便能够在所有使用指针。这也可以在结构显示,其中有各种不同大小的元素。该结构可以是一个很好的边界​​上开始了。此外,编译器仍然可以引入松弛叮咬在结构中的内部来完成需要它的结构元素的正确对齐。

The basis for the aliasing rule is the fact that compilers may place values of different simple types on different memory boundaries to improve access and that hardware in some cases may require such alignment to be able to use the pointer at all. This can also show up in structs where there is a variety of different-sized elements. The struct may be started out on a good boundary. In addition, the compiler may still introduce slack bites in the interior of the struct to accomplish proper alignment of the struct elements that require it.

考虑到编译器往往对如何控制这一切的处理,或不选择,你可以看到,有可能发生意外多方面的。这是特别重要的是要知道传递指针时,结构(转换为字符*或不)成汇编期待不同的排列公约库。

Considering that compilers often have options for controlling how all of this is handled, or not, you can see that there are many ways that surprises can occur. This is particularly important to be aware of when passing pointers to structs (cast as char* or not) into libraries that were compiled to expect different alignment conventions.

有关的char *什么?

What about char*?

有关的char *的presumption是的sizeof(字符)== 1(相对于其他规模可观的数据的大小)和字符*指针没有任何对齐要求。所以,一个真正的char *总是可以安全地通过周围,没有对齐的关注成功使用,而且也适用于一个char []数组中的任何元素,表演++和 - 的指针,等等。 (奇怪的是,无效*是不太一样的。)

The presumption about char* is that sizeof(char) == 1 (relative to the sizes of all other sizable data) and that char* pointers don't have any alignment requirement. So a genuine char* can always be safely passed around and used successfully without concern for alignment, and that goes for any element of a char[] array, performing ++ and -- on the pointers, and so on. (Oddly, void* is not quite the same.)

现在,你应该能够看到,如果你传递某种结构的数据到一个char []数组,这不是本身适当对齐,试图投退给确实需要对齐(S)的指针可以是一个严重问题。

Now you should be able to see how if you transfer some sort of structure data into a char[] array that was not itself aligned appropriately, attempting to cast back to a pointer that does require alignment(s) can be a serious problem.

如果你让一个char []数组和结构,要求最苛刻的对齐工会(即,该结构的)将被编译器荣幸。这将如果供应商与消费者的有效利用匹配工会所以结构*的是铸造为char *和背部的作品就好工作。

If you make a union of a char[] array and a struct, the most-demanding alignment (i.e., that of the struct) will be honored by the compiler. This will work if the supplier and the consumer are effectively using matching unions so that casting of the struct* to char* and back works just fine.

在这种情况下,我希望数据是在一个类似工会的创建被赶前指针,它为char *或转移任何其他方式作为的sizeof(char)的字节数组。同样重要的是确保任何编译器选项所依赖的库和你自己的code之间的兼容。

In that case, I would hope that the data was created in a similar union before the pointer to it was cast to char* or it was transferred any other way as an array of sizeof(char) bytes. It is also important to make sure any compiler options are compatible between the libraries relied upon and your own code.

这篇关于当为char *安全进行严格的指针别名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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