试图了解static_cast中的预期行为

我正在尝试了解static_cast的一些细节。

请查看以下代码,

struct A
{
    int data = 0;
};

void foo(const A* a)
{
    (*static_cast<A**>(static_cast<void*>(&a)))->data = 1;
}

void bar(const A* a)
{
    const_cast<A*>(a)->data = 1;
}

int main()
{
    A a;
    foo(&a);
    return a.data;
}

函数foo是否有效的C ++代码? 与foobar相比,是否有任何有效用法能带来不同的结果?

a10440377 回答:试图了解static_cast中的预期行为

两个函数都是有效的C ++,并且在C ++ 11和更高版本中具有明确定义的行为(修改在data中创建的A对象的main成员)。

您可以直接通过const或通过const间接访问{{1}从指向const_cast对象类型的指针中获取指向非static_cast的指针}},就像您在void*中所做的那样。这本身不是问题:

可以强制转换为foo,因为void*是指向&a的指针,而const A*没有(顶级)cv限定。从void*A**的转换是可能的,因为void*可以转换为任何对象指针类型。取消引用的结果是通过指向const A*的指针访问A*对象,但是访问is ok的原因是类型是similar。 (最后一部分seems违反了C ++ 11之前的别名规则,使行为未定义。)

但是,通过以这种方式获得的指向非const的指针修改const合格对象会导致未定义的行为。

由于您要传递给函数的对象A a;不符合const的条件,所以没有问题。

但是我认为很明显为什么使用这样的功能很危险。将声明A a;更改为const A a;仍然可以编译,因为没有类型不匹配,但是行为不确定。

据我所知,这两个函数在所有情况下都具有完全相同的作用。

本文链接:https://www.f2er.com/3169466.html

大家都在问