强制转换为无效*并返回到原始数据类型* 我已经多次看到并使用了C++,特别是在各种线程实现中。我想知道的是,这样做是否存在任何陷阱/问题?当我们铸造void*并再次铸造时,是否有任何方法可以使我们遇到错误或未定义的条件?如果存在这样的问题,我们应该如何解决
多谢各位 我想知道的是,这样做是否存在任何陷阱/问题? 在将强制转换为无效*并返回到原始数据类型* 我已经多次看到并使用了C++,特别是在各种线程实现中。我想知道的是,这样做是否存在任何陷阱/问题?当我们铸造void*并再次铸造时,是否有任何方法可以使我们遇到错误或未定义的条件?如果存在这样的问题,我们应该如何解决,c++,casting,void-pointers,C++,Casting,Void Pointers,多谢各位 我想知道的是,这样做是否存在任何陷阱/问题? 在将void*强制转换回特定类型时,您需要绝对确定,如果不这样做,您将导致未定义的行为和潜在的灾难。一旦你使用了void*你就失去了类型安全性。很难跟踪avoid*类型实际指向的是什么,也无法保证或确定它确实指向你要将其类型转换回的类型 当我们铸造void*并再次铸造时,是否有任何方法会导致错误或未定义的情况? 是的,#1中提到的场景 如果存在此类问题,我们应如何解决? 避免在C++中完全使用 Vult*/Cuff>,而使用模板和继承。 在
void*
强制转换回特定类型时,您需要绝对确定,如果不这样做,您将导致未定义的行为和潜在的灾难。一旦你使用了void*
你就失去了类型安全性。很难跟踪avoid*
类型实际指向的是什么,也无法保证或确定它确实指向你要将其类型转换回的类型
当我们铸造void*并再次铸造时,是否有任何方法会导致错误或未定义的情况?
是的,#1
中提到的场景
如果存在此类问题,我们应如何解决? <>避免在C++中完全使用<代码> Vult*/Cuff>,而使用模板和继承。 在C语言中,在某些情况下,您可能绝对需要它,但请尽量减少它的使用。
底线,
C/C++允许你开枪自杀,这取决于你是否这样做。我知道驱动程序中有很多函数等。使用void指针将数据返回给调用方,模式基本相同:
int requestSomeData(int kindOfData, void * buffer, int bufferSize);
此函数可以采用不同的数据类型作为参数。
他们所做的是使用bufferSize作为参数,以避免写入不应该写入的内存位置。
如果bufferSize不匹配或小于应返回的数据,则函数将返回错误代码
无论如何:在编写任何代码之前避免使用它们或三思而后行。 < P>我在C++中有“强”>不< /强>向
void*
将删除所有类型安全
如果您使用reinterpret\u cast
或static\u cast
将指针类型转换为void*
并返回到相同的指针类型,标准实际上保证了结果将得到良好定义
危险在于您可能会将
void*
投射到错误的类型,因为您不再确定正确的类型。标准授予的唯一东西是,给定a*pa
,(a*)(void*)pa==pa
。
结果
void* pv = pA;
A* pA2 = (A*)pv;
pA2->anything ...
将与pA->任何内容相同…
其他一切都是“未定义的”,实际上,ad在某种程度上依赖于实现
根据我的经验,以下是一些已知的陷阱:
- 将
派生形式A
、B
和pA
视为pB
和A*
B*
使pB=pA
指向pB
的底部。这并不意味着A
和pB
是同一个地址。因此,pA
实际上可以将其他任何地方指向A(尽管单个继承对象通常是共享同一个源实现的,所以它显然工作得很好)pB=(B*)(void*)pA
- 反之亦然:假设
实际上指向pB
,A
不一定正确指向A对象。正确的方法是pA=(A*)(void*)pB
pA=static_cast(pB)代码>
- 如果上面的点可以与大多数单继承实现一起工作,那么对于除了第一个碱基以外的碱基将永远不起作用:考虑<代码>类A:public z,public b{}{};code>如果
不为空,给定Z
,则A
子组件将不具有相同的A地址。(C++中的多重继承到处都是IoFixis)B
- 有时情况也取决于平台:
(其中(char*)(void*)pI
指向一个整数)将与“pI
如果*pI
在(-128..+127)”中不同(仅在小端机器上)*pI
一般来说,不要假设类型之间的转换只会改变地址的解释方式 “如果存在这样的问题,我们应该如何解决?”不要使用
void*
。void*
是一个非常强大的构造,但同样危险,因为无法知道为什么会出问题。当你使用它的时候,你必须非常小心。你能给出一个例子(代码)吗?我能想到你必须这样做的情况。但一般来说,尽可能避免使用void*。现在,您通常可以使用标准线程库(如果没有,也可以使用Boost的类似库),而不是“各种线程实现”。这不需要在用户代码中进行任何不可靠的指针转换。