Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
强制转换为无效*并返回到原始数据类型* 我已经多次看到并使用了C++,特别是在各种线程实现中。我想知道的是,这样做是否存在任何陷阱/问题?当我们铸造void*并再次铸造时,是否有任何方法可以使我们遇到错误或未定义的条件?如果存在这样的问题,我们应该如何解决_C++_Casting_Void Pointers - Fatal编程技术网

强制转换为无效*并返回到原始数据类型* 我已经多次看到并使用了C++,特别是在各种线程实现中。我想知道的是,这样做是否存在任何陷阱/问题?当我们铸造void*并再次铸造时,是否有任何方法可以使我们遇到错误或未定义的条件?如果存在这样的问题,我们应该如何解决

强制转换为无效*并返回到原始数据类型* 我已经多次看到并使用了C++,特别是在各种线程实现中。我想知道的是,这样做是否存在任何陷阱/问题?当我们铸造void*并再次铸造时,是否有任何方法可以使我们遇到错误或未定义的条件?如果存在这样的问题,我们应该如何解决,c++,casting,void-pointers,C++,Casting,Void Pointers,多谢各位 我想知道的是,这样做是否存在任何陷阱/问题? 在将void*强制转换回特定类型时,您需要绝对确定,如果不这样做,您将导致未定义的行为和潜在的灾难。一旦你使用了void*你就失去了类型安全性。很难跟踪avoid*类型实际指向的是什么,也无法保证或确定它确实指向你要将其类型转换回的类型 当我们铸造void*并再次铸造时,是否有任何方法会导致错误或未定义的情况? 是的,#1中提到的场景 如果存在此类问题,我们应如何解决? 避免在C++中完全使用 Vult*/Cuff>,而使用模板和继承。 在

多谢各位

我想知道的是,这样做是否存在任何陷阱/问题?

在将
void*
强制转换回特定类型时,您需要绝对确定,如果不这样做,您将导致未定义的行为和潜在的灾难。一旦你使用了
void*
你就失去了类型安全性。很难跟踪a
void*
类型实际指向的是什么,也无法保证或确定它确实指向你要将其类型转换回的类型

当我们铸造void*并再次铸造时,是否有任何方法会导致错误或未定义的情况?

是的,
#1
中提到的场景


如果存在此类问题,我们应如何解决?

<>避免在C++中完全使用<代码> Vult*/Cuff>,而使用模板和继承。 在C语言中,在某些情况下,您可能绝对需要它,但请尽量减少它的使用。
底线,

C/C++允许你开枪自杀,这取决于你是否这样做。

我知道驱动程序中有很多函数等。使用void指针将数据返回给调用方,模式基本相同:

int requestSomeData(int kindOfData, void * buffer, int bufferSize);
此函数可以采用不同的数据类型作为参数。 他们所做的是使用bufferSize作为参数,以避免写入不应该写入的内存位置。 如果bufferSize不匹配或小于应返回的数据,则函数将返回错误代码


无论如何:在编写任何代码之前避免使用它们或三思而后行。

< P>我在C++中有“强”>不< /强>向Vult*/Cuff>的可视化转换。C++中主动避免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
    是同一个地址。因此,
    pB=(B*)(void*)pA
    实际上可以将其他任何地方指向A(尽管单个继承对象通常是共享同一个源实现的,所以它显然工作得很好)
  • 反之亦然:假设
    pB
    实际上指向
    A
    pA=(A*)(void*)pB
    不一定正确指向A对象。正确的方法是
    pA=static_cast(pB)
  • 如果上面的点可以与大多数单继承实现一起工作,那么对于除了第一个碱基以外的碱基将永远不起作用:考虑<代码>类A:public z,public b{}{};code>如果
    Z
    不为空,给定
    A
    ,则
    B
    子组件将不具有相同的A地址。(C++中的多重继承到处都是IoFixis)
  • 有时情况也取决于平台:
    (char*)(void*)pI
    (其中
    pI
    指向一个整数)将与“
    *pI
    如果
    *pI
    在(-128..+127)”中不同(仅在小端机器上)

一般来说,不要假设类型之间的转换只会改变地址的解释方式

“如果存在这样的问题,我们应该如何解决?”不要使用
void*
void*
是一个非常强大的构造,但同样危险,因为无法知道为什么会出问题。当你使用它的时候,你必须非常小心。你能给出一个例子(代码)吗?我能想到你必须这样做的情况。但一般来说,尽可能避免使用void*。现在,您通常可以使用标准线程库(如果没有,也可以使用Boost的类似库),而不是“各种线程实现”。这不需要在用户代码中进行任何不可靠的指针转换。