似乎有两种类型的 C++。实用C++和语言律师C++。在某些情况下,能够将一种类型的位模式解释为一种不同的类型会很有用。浮点技巧就是一个显着的例子。让我们取著名的快速平方根反比(取自Wikipedia,又取自此处):
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); …Run Code Online (Sandbox Code Playgroud) 例如,我有这个结构
struct A {
float x;
float y;
float z;
};
Run Code Online (Sandbox Code Playgroud)
我可以这样做吗?A a; float* array = (float*)&a;
并使用as float数组?
由于C++ 11 std::complex<T>[n]保证T[n*2]具有可定义的值,因此具有良好定义的值.这正是人们对任何主流架构的期望.对于我自己的类型,这种保证是否可以通过标准C++实现,struct vec3 { float x, y, z; }或者只有在编译器的特殊支持下才能实现?
在各种3d数学代码库中,我有时会遇到这样的事情:
struct vec {
float x, y, z;
float& operator[](std::size_t i)
{
assert(i < 3);
return (&x)[i];
}
};
Run Code Online (Sandbox Code Playgroud)
其中,AFAIK是非法的,因为允许实现在成员之间虚假地添加填充,即使它们属于同一类型,但实际上没有人会这样做.
通过static_asserts 施加约束可以使这变得合法吗?
static_assert(sizeof(vec) == sizeof(float) * 3);
Run Code Online (Sandbox Code Playgroud)
即static_assert没有被触发意味着operator[]什么是预期的并且不会在运行时调用UB?
c++ strict-aliasing language-lawyer type-punning structure-packing