C++ 将int*const强制转换为long int*const警告
以前可能有人以其他方式问过这个问题(如果不是的话,我会感到惊讶),但如果是的话,我很难找到它 鉴于:C++ 将int*const强制转换为long int*const警告,c++,casting,const-pointer,C++,Casting,Const Pointer,以前可能有人以其他方式问过这个问题(如果不是的话,我会感到惊讶),但如果是的话,我很难找到它 鉴于: #包括 #包括 int main() { int*常数pi=新的int(1); 长整型*常数pl=重新解释型(pi); std::coutlong int*const是指向可变数据的不可变指针 reinterpret\u cast返回一个临时对象。在大多数临时对象(包括此对象)上,顶级类型的不变性是无关的 这: 导致您的程序显示未定义的行为。指向的对象不是long int,它是int,并且您正在
#包括
#包括
int main()
{
int*常数pi=新的int(1);
长整型*常数pl=重新解释型(pi);
std::coutlong int*const
是指向可变数据的不可变指针
reinterpret\u cast
返回一个临时对象。在大多数临时对象(包括此对象)上,顶级类型的不变性是无关的
这:
导致您的程序显示未定义的行为。指向的对象不是long int
,它是int
,并且您正在作为类型不同的对象访问它
<代码> RealTytRask不是“把这些字节当作不同的类型”,尽管很多人都这样对待。这些操作在C++标准下几乎总是未定义的行为。
将对象A的字节解释为类型B的对象(当它们是适当的普通类型时)的正确方法是使用类似于memcpy
的东西
int * const pi = new int(1);
long int l = 0;
static_assert( sizeof(*pi) == sizeof(l) );
::memcpy( &l, pi, sizeof(l) ); // or l = std::bit_cast<long int>(*pi) in C++20
std::cout << "val: " << l << std::endl;
int*constpi=newint(1);
长整数l=0;
静态断言(sizeof(*pi)=sizeof(l));
::memcpy(&l,pi,sizeof(l));//或C++20中的l=std::bit_cast(*pi)
std::我可以更好奇关于打破严格别名的问题以及由此产生的未定义行为。更不用说如果sizeof(long int)!=sizeof(int)会出现的问题
。你到底想做什么?这种cast应该解决的实际问题是什么?无关:由于在*pl
处存在严格的别名冲突,程序显示UB。或者,更好的是,如果你有C++20,你可以使用std::bit_cast
而不是memcpy
。答案很好-我没有把mu在std::cout部分中,我只是添加了它,甚至没有仔细考虑,但它并不相关。在实际代码中,我们知道该位置包含4个字节+的数据,它只有一个函数读取32位字节,指针指向16位字节(上面的示例不是相同的类型)-但我们很高兴他们复制了正确大小的数据。删除const成功了-非常感谢:)@code\u fodder允许这样做的方法非常有限。“有多少内存”是不够的。通常只依赖“有多少内存”将通过您的测试,但您的程序仍显示未定义的行为,并且编译器更新或对程序的不相关部分进行看似未关联的更改可能会破坏您的代码。问题在cout
行较少,而在reinterpret\u cast
行较多;但UB仅在使用以任何非平凡的方式重新解释\u cast
。@hoz还不太清楚,只在c++17:o@Yakk-AdamNevraumont哦,我明白了。那么,如果我使用结果传递到一个复制函数(比如memcpy),我假设这是一个微不足道的(ok)用法?
long int * const pl = reinterpret_cast<long int * const>(pi);
long int * const pl = reinterpret_cast<long int *>(pi);
std::cout << "val: " << *pl << std::endl;
int * const pi = new int(1);
long int l = 0;
static_assert( sizeof(*pi) == sizeof(l) );
::memcpy( &l, pi, sizeof(l) ); // or l = std::bit_cast<long int>(*pi) in C++20
std::cout << "val: " << l << std::endl;