小编c--*_*c--的帖子

如何在不违反类型别名规则的情况下解释消息有效负载?

我的程序通过网络接收消息.这些消息被一些中间件(即其他人无法更改的代码)反序列化.我的程序接收到如下所示的对象:

struct Message {
    int msg_type;
    std::vector<uint8_t> payload;
};
Run Code Online (Sandbox Code Playgroud)

通过检查,msg_type我可以确定消息有效负载实际上是,例如,uint16_t值数组.我想在没有不必要的副本的情况下读取该数组.

我的第一个想法是这样做:

const uint16_t* a = reinterpret_cast<uint16_t*>(msg.payload.data());
Run Code Online (Sandbox Code Playgroud)

但是阅读a似乎违反了标准.这是第3.10.10条:

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:

  • 对象的动态类型,
  • 一个cv限定版本的动态类型的对象,
  • 与对象的动态类型类似的类型(如4.4中所定义),
  • 与对象的动态类型对应的有符号或无符号类型的类型,
  • 一种类型,是有符号或无符号类型,对应于对象动态类型的cv限定版本,
  • 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合或包含联合的元素或非静态数据成员),
  • 一个类型,它是对象动态类型的(可能是cv限定的)基类类型,
  • a charunsigned char类型.

在这种情况下,a将是glvalue并且uint16_t*似乎不符合任何列出的标准.

那么如何在uint16_t不调用未定义的行为或执行不必要的副本的情况下将有效负载视为值数组?

c++

31
推荐指数
2
解决办法
2192
查看次数

JIT 编译器可以做什么 AOT 编译器不能做的事情?

即时 (JIT) 编译器可以根据提前 (AOT) 编译器无法获得的运行时信息来优化程序。

该运行时信息最明显的示例是目标平台,例如运行程序的确切CPU,或可能可用的任何加速器(例如GPU)。这就是 OpenCL 是 JIT 编译的意义。

但是假设我们提前知道目标平台是什么:我们知道哪些 SIMD 扩展可用,等等。 JIT 编译器还可以利用 AOT 编译器无法利用的其他运行时信息吗?

HotSpot 风格的 JIT 编译器会自动优化程序的热点……但是 AOT 编译器不能只优化整个程序、热点等等吗?

我想要一些 JIT 编译器可以执行而 AOT 编译器无法执行的特定优化的示例。如果您能够提供任何证据证明此类优化在“现实世界”场景中的有效性,则可获得加分。

compiler-construction optimization jit compiler-optimization

6
推荐指数
1
解决办法
1250
查看次数

为什么这种类型的惩罚不是未定义的行为?

这是一个玩具示例,我认为会调用未定义的行为:

#include <cstdint>
#include <iostream>
#include <vector>

int
main()
{
    std::vector<uint16_t> foo = {0, 0x42F6};
    std::cout << *reinterpret_cast<float*>(foo.data()) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我很确定取消引用它的结果reinterpret_cast会违反严格的别名规则.然而:

$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
$ g++ -fstrict-aliasing -Wstrict-aliasing -fsanitize=undefined -std=c++14 -o a a.cpp
$ ./a
123
Run Code Online (Sandbox Code Playgroud)

没有来自编译器或UB消毒剂的警告.为什么不?

c++ undefined-behavior type-punning

1
推荐指数
2
解决办法
113
查看次数