简体   繁体   English

使用数据缓冲区而不会违反严格的别名

[英]Using a data buffer without violating strict aliasing

I want to rewrite a piece of (old) code to be standards compliant. 我想重写一段(旧的)代码以符合标准。 The old code uses a buffer to store a POD-struct and a checksum to send it over the network and receive it. 旧代码使用缓冲区存储POD结构和校验和,以通过网络发送并接收它。 For sending, the code looks like: 对于发送,代码如下:

struct MessageStruct {int a; float b;};

char buffer[sizeof(MessageStruct) + sizeof(uint32_t)];
((MessageStruct*)buffer)->a = 12;
((MessageStruct*)buffer)->b = 3.14159f;
*((uint32_t*)(buffer + sizeof(MessageStruct))) = 9876;

// Use the data buffer in some way.
SendMessage(buffer, sizeof(buffer));

For receiving, the code looks like: 对于接收,代码如下:

struct MessageStruct {int a; float b;};

// Receive: char *buffer, int size
const MessageStruct *message = (MessageStruct*)buffer;
uint32_t checksum = *((uint32_t*)(buffer + sizeof(MessageStruct)));

How do I update this code to make it fully standards complaint, in particular not in violation of the strict aliasing rule? 如何更新此代码以使其完全成为标准投诉,尤其是不违反严格的别名规则?

I've found posts addressing similar issues: strict aliasing and alignment , Shared memory buffers in C++ without violating strict aliasing rules . 我发现了解决类似问题的帖子: 严格的别名和对齐C ++中的共享内存缓冲区而没有违反严格的别名规则 However, none of these really answer my question; 但是,这些都不能真正回答我的问题。 or maybe they do, but then I don't see it. 也许他们会,但是我看不到。

Update: As some of the answers have already stated, the easiest way is to use memcpy . 更新:正如一些答案已经指出的那样,最简单的方法是使用memcpy I am wondering, is there any way to do this using placement new, or another construct that negates the need for copying and constructs it in-place? 我想知道,有没有办法使用新的placement来进行此操作,或者使用另一种否定复制并就地构建的构造?

在您的情况下,避免违反严格的别名规则的最简单方法是将memcpy()填充到缓冲区中。

Use memcpy : 使用memcpy

MessageStruct msg;
msg.a = 12;
msg.b = 3.14;
uint32_t n = 9876;

memcpy(buffer, &msg, sizeof(msg));
memcpy(buffer + sizeof(msg), &n, sizeof(n));

Firstly, your very approach of sending the in-memory representation of a struct to a different machine is flawed, because the other machine might have a different layout or even size than yours. 首先,将结构的内存表示形式发送到另一台计算机的方法是有缺陷的,因为另一台计算机的布局甚至大小可能与您的不同。 Use a properly defined metaformat like JSON, XML or something like that. 使用正确定义的元格式,例如JSON,XML或类似的格式。

Now, if you just don't care about such flaws, you can take your own approach one step further: 现在,如果您不关心此类缺陷,则可以将自己的方法更进一步:

struct MessageStructWithChecksum:
    MessageStruct
{
    uint32_t checksum;
};

Apart from the conversions between struct and raw bytes, no aliasing questions. 除了在struct字节和原始字节之间进行转换外,没有任何别名问题。 Also note that you can define function-local structures and that you can write a template for use with different message types. 还要注意,您可以定义局部函数结构,并且可以编写用于不同消息类型的模板。

The Send part is easiest: 发送部分最简单:

struct MessageStruct {int a; float b;};
struct MessageStructWithCheckSum { MessageStruct s; uint32_t check_sum;};

MessageStructWithCheckSum m;
m.s.a = 12;
m.s.b = 3.14159f;
m.check_sum = 9876;

// Use the data buffer in some way.
SendMessage(reinterpret_cast<const unsigned char*>(m), sizeof(m));

You can access the stored value of an object through [..] a char or unsigned char type. 您可以通过[..] char或unsigned char类型访问对象的存储值。

For the read part, I think that you have to copy to avoid strict aliasing rules. 对于阅读部分,我认为您必须复制以避免严格的别名规则。

But in fact, you have to do special treatment to manage endianness (and types with representation which can be different), which is sort of copy anyway. 但是实际上,您必须进行特殊处理以管理字节序(以及表示形式可能不同的类型),无论如何这都是一种复制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不违反严格别名规则的情况下解析字节数组? - How to parse byte array without violating strict aliasing rule? 在不违反严格的别名规则的情况下访问进程间共享内存中的对象 - Access object in interprocess shared memory without violating strict aliasing rules C ++中的共享内存缓冲区,不违反严格的别名规则 - Shared memory buffers in C++ without violating strict aliasing rules 甚至在不进行任何强制转换的情况下也违反了严格混叠? - Violating strict-aliasing, even without any casting? 缓冲区填充了不同类型的数据,并进行了严格的别名处理 - Buffer filled with different types of data, and strict aliasing 在不违反“严格别名”的情况下使用 std::array&amp; 分配 C 样式数组的一个子部分并因此调用 UB? - Assigning a subsection of C-style array using a std::array& without violating "strict aliasing" and hence invoking UB? 如何在不违反严格别名规则的情况下访问内存映射的多字节寄存器? - How can memory mapped multi-byte registers be accessed without violating the strict aliasing rule? `u8string_view` 转换成 `char` 数组而不违反严格混叠? - `u8string_view` into a `char` array without violating strict-aliasing? 调用FFTW的就地实数到复数变换,而不违反严格的混叠规则 - Calling FFTW's in-place real-to-complex transform without violating strict aliasing rules 有效地生成字节缓冲区而不破坏严格的别名 - Efficiently generating byte buffer without breaking strict aliasing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM