在此实例中,三元运算符与 C 风格的指针向上转换相结合会调用未定义的行为吗?
Does the ternary operator combined with C-style upcasting of pointers invoke undefined behavior in this instance?
激励背景:在尝试调试我的软件中一个难以重现的故障条件时,我遇到了一些有问题的指针转换代码,这些代码是由一个天真的初级开发人员编写的(好吧,我承认,它是我,10 年前),我怀疑这可能是故障的根本原因。
我重写了代码以使用适当的 static_cast<>
调用,自重写以来我还没有看到故障情况发生,但这并不一定意味着任何故障,因为故障很少发生;到目前为止,我可能只是“走运”。
我的问题是:在下面的代码中 main()
中执行的 C 风格的指针向上转换是否会调用未定义的行为?或者它只是丑陋,但从语言律师的角度来看仍然是格式正确的?
#include <stdio.h>
#include <stdlib.h>
class BaseClass
{
public:
BaseClass() {}
virtual ~BaseClass() {}
virtual void Foo() {printf("BaseClass::Foo() called\n");}
};
class SubClassA : public BaseClass
{
public:
SubClassA() {}
virtual void Foo() {printf("SubClassA::Foo() called\n");}
};
class SubClassB : public BaseClass
{
public:
SubClassB() {}
virtual void Foo() {printf("SubClassB::Foo() called\n");}
};
int main(int, char **)
{
SubClassA a;
SubClassB b;
// Warning: questionable C-style casting follows...
BaseClass * p = (rand()%2) ? ((BaseClass*)(&a)) : ((BaseClass*)(&b));
p->Foo();
return 0;
}
演员阵容完全合法。来自 [expr.cast]/4.6
a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;
激励背景:在尝试调试我的软件中一个难以重现的故障条件时,我遇到了一些有问题的指针转换代码,这些代码是由一个天真的初级开发人员编写的(好吧,我承认,它是我,10 年前),我怀疑这可能是故障的根本原因。
我重写了代码以使用适当的 static_cast<>
调用,自重写以来我还没有看到故障情况发生,但这并不一定意味着任何故障,因为故障很少发生;到目前为止,我可能只是“走运”。
我的问题是:在下面的代码中 main()
中执行的 C 风格的指针向上转换是否会调用未定义的行为?或者它只是丑陋,但从语言律师的角度来看仍然是格式正确的?
#include <stdio.h>
#include <stdlib.h>
class BaseClass
{
public:
BaseClass() {}
virtual ~BaseClass() {}
virtual void Foo() {printf("BaseClass::Foo() called\n");}
};
class SubClassA : public BaseClass
{
public:
SubClassA() {}
virtual void Foo() {printf("SubClassA::Foo() called\n");}
};
class SubClassB : public BaseClass
{
public:
SubClassB() {}
virtual void Foo() {printf("SubClassB::Foo() called\n");}
};
int main(int, char **)
{
SubClassA a;
SubClassB b;
// Warning: questionable C-style casting follows...
BaseClass * p = (rand()%2) ? ((BaseClass*)(&a)) : ((BaseClass*)(&b));
p->Foo();
return 0;
}
演员阵容完全合法。来自 [expr.cast]/4.6
a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;