在我正在研究的一些代码中,我有一些这种模式的实例:
Foo *foo = ...;
// do stuff with foo
if (foo->type == ActuallyBar) {
Bar *bar = reinterpret_cast<Bar*>(foo);
// do stuff with bar
if (bar->type == ActuallyQux) {
Qux *qux = reinterpret_cast<Qux*>(bar);
// do stuff with qux
}
}
(我知道这是一个糟糕的C ++反模式,例如“愚蠢的多态”,但它是旧代码,需要大量工作才能进行大修)。更糟糕的是,没有保证的继承链(例如Qux继承自Foo的继承可能无法保证,但保证这可能是一个更现实的重构 - 让我知道你的想法:))
我的问题是关于别名。在do stuff with qux
,指针qux
和bar
指向同一个对象。我知道这在C ++中是危险的,因为这两个指针指向不同的类型。
但是,此时我不需要更多地使用变量bar
(qux
就足够了。)
是否有一种很好的方法可以禁用关于这两个指针的任何别名假设?
我有一个想法是
union {
Foo *foo;
Bar *bar;
Qux *qux;
} all;
all.foo = ...;
// do stuff with foo
if (all.foo->type == ActuallyBar) {
all.bar = reinterpret_cast<Bar*>(all.foo);
// do stuff with bar
if (all.bar->type == ActuallyQux) {
all.qux = reinterpret_cast<Qux*>(all.bar);
// do stuff with qux
}
}
但我不确定这会奏效。
感谢您的任何建议!抱歉用这种可怕的反模式召唤恶魔!
答案 0 :(得分:0)
您可以在不同的翻译单元中破坏代码并禁用链接时间优化:
file.cpp
Foo *foo = ...;
// do stuff with foo
if (foo->type == ActuallyBar)
do_stuff_with_bar(reinterpret_cast<Bar*>(foo));
file2.cpp
void do_stuff_with_bar(Bar* bar){
//...
if (bar->type == ActuallyQux)
do_stuff_with_qux(reinterpret_cast<Qux*>(bar);
}
file3.cpp ...
这可能会降低您的代码效率,但至少它会完成预期的工作。
答案 1 :(得分:0)
对于Gcc样式编译器(如gcc和clang),您可以使用-fno-strict-aliasing选项