从union中的long类型强制转换为char*类型,然后再返回,会做什么?
What does this cast from long in a union to char* and back do?
我正在检查一个简单的可执行打包程序的代码,它将一个部分写入可执行文件中,在启动时解包它,当我偶然发现这段代码:
void setDistance( unsigned long size )
{
char* set = (((char *)I)+pUnpacker->VirtualAddress);
union
{
short sh[2];
long l;
} conv;
conv.l = size;
conv.sh[0] = 0;
unpacker_set(set, (char *)(&conv.l), 4, TEXT_DISTANCE);
}
Size是从内存中的解压缩代码到要解压缩的Section开头的距离。在加载器代码中,它被定义为unsigned long。另一方面,Unpacker_set有这样的代码:
void inline unpacker_set( char* at, char* what, size_t size, unsigned long sig )
{
DWORD oldprotect;
unsigned char *set = (unsigned char *)at;
while(*((unsigned long*)(set)) != sig)
set++;
if(VirtualProtect(set, size, PAGE_READWRITE, &oldprotect) == TRUE)
for(unsigned i=0; i<size; i++)
*(set+i) = *(what+i);
}
虽然我理解第二个例程替换了来自解包程序代码的值,但我想知道为什么使用联合的麻烦是完成的。
理解代码的最好方法可能是编写一个非常小的测试用例,看看它做了什么:
#include <iostream>
void f()
{
union
{
short sh[2];
long l ;
} conv ;
conv.l = 100000000 ;
std::cout << std::hex << conv.l << std::endl ;
conv.sh[0] = 0 ;
std::cout << std::hex << conv.l << std::endl ;
}
int main()
{
f() ;
}
我看到的输出如下:
5f5e100
5f50000
因此,代码意图看起来像是试图掩盖大小的高阶位,尽管这是非常丑陋的,它不太可能是可移植的。
正如David指出的,你应该意识到严格的混叠。这篇类型双关语和严格混叠的文章甚至更好,因为它有一些使用union
的真实世界问题的可靠示例。因此,为了确保此代码按预期工作,假设gcc
或clang
,您需要传入以下命令行参数-fno-strict-aliasing
。
相关文章:
- '{'标记之前的预期类名,然后在预声明时无效使用不完整的类型'class class_name'
- 如何对绑定的成员方法进行typedef,然后将该类型用作模板参数
- 将函数应用于元组中的每个元素,将每个元素强制转换为类型包中的不同类型,然后作为参数包传递
- 强制复制(然后销毁)仅移动类型
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 如何将对象定义为一种类型,然后再将其声明为子类型
- 将转换范围缩小到更大的类型(然后再回来)
- static_cast到其他类型,然后移动结果
- 我可以做一个不形式的写入文件,然后从文件中进行整体类型的格式读取
- C/C++对一块内存进行malloc,然后对不同的任意类型使用不同的部分
- c++我需要将文件中的数据读取到多维数组中,然后用一种数据类型对数组进行排序.怎样
- 如何将 void 指针类型转换为 int 指针,然后在其中存储 int
- 复制构造,然后访问任意POD类型
- 为什么一旦我将引用声明为 const 然后它可以采用不同类型的数据?
- 对更复杂/结构化的类型使用boost::stream,然后使用chars
- 在C++中,我们可以向上转换一个数组,然后尝试将另一个子类型放入其中吗(灵感来自Java ArrayStoreExcep
- c++ 11: bind std::sort用于用户定义的类型,然后使用该绑定作为ctor的参数
- 如何在类名careercenter中定义数组类型customers,然后在.cpp文件中定义create, modify
- 为什么将类型转换为指针然后解引用可以工作?
- c++(98) STL是否可以设置对int类型的数组进行散列,然后检查该数组是否存在于集合中?