C ++:显式禁用指针的

时间:2018-02-18 09:14:53

标签: c++ pointers alias

在我正在研究的一些代码中,我有一些这种模式的实例:

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,指针quxbar指向同一个对象。我知道这在C ++中是危险的,因为这两个指针指向不同的类型。

但是,此时我不需要更多地使用变量barqux就足够了。)

是否有一种很好的方法可以禁用关于这两个指针的任何别名假设?

我有一个想法是

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
    }
}

但我不确定这会奏效。

感谢您的任何建议!抱歉用这种可怕的反模式召唤恶魔!

2 个答案:

答案 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选项