boost :: optional <>はシンプルなデータ型には最適ですが、インターフェイスを実装するクラスから継承するクラスに使用すると、厳密なエイリアシングが有効な場合に失敗します。仮想関数を継承するクラスに対してboost :: optionalが失敗するのはなぜですか?
例:以下の使用してgccのバージョン4.4.3でコンパイル
#include <boost/optional.hpp>
struct MyLine{
double a;
double b;
};
class Edge{
public:
MyLine toMyLine() const;
private:
virtual MyLine doToMyLine() const =0;
};
class Wall:public Edge {
public:
Wall(MyLine const& seg):mMyLine(seg){};
private:
MyLine doToMyLine() const{return MyLine();};
MyLine mMyLine;
};
class SimpleWall {
public:
SimpleWall(MyLine const& seg):mMyLine(seg){};
private:
MyLine mMyLine;
};
int main(){
//boost::optional<Wall> res; //fails with strict aliasing error
boost::optional<SimpleWall> res2; //compiles just fine
}
これは誤りである。この問題を解決するための最良の方法です
g++ -c -pipe -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Werror -std=c++0x -O2 -Wall -W -I/usr/local/boost_1_44_0 -o obj/main.o main.cpp
何。厳密なエイリアシングの警告を有効にしておきたいと思います。私はブーストバージョン1.44を使用しています。
更新日:
悪化します!次のコードを考えてみましょう:
これはコンパイルgccのバージョン4.4.3を使用して、以下でコンパイル#include <boost/optional.hpp>
class MyBase{
public:
int toFoo() const;
private:
virtual int doToFoo() const =0;
};
class Child:public MyBase {
public:
Child(int const& foo):mFoo(foo){};
private:
int doToFoo() const{return 0;}
int mFoo;
};
int main(){
boost::optional<int> optint; //comment out for surprise
optint.get(); //comment out for surprise
boost::optional<Child> res2;
res2.get();
}
:
g++ -c -pipe -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Werror -std=c++0x -O2 -Wall -W -I/usr/local/boost_1_44_0 -o obj/main.o main.cpp
の行は「//驚きのためにコメントアウトは」私は、コメントアウトされているが付いている場合厳密なエイリアシング警告を得る。私はこれを少なくとも20回チェックした。これは私が今までに見た変わったことの一つです。 boost :: optionalはsthを初期化するように見えます。そのテンプレートパラメータから独立しているか、stccで呼び出された場合のみboost :: optionalを理解するgccのようになります。簡単な最初。何か案は ?
あなたは厳しいエイリアシングの話をしているので、我々はあなたがGCCを使用していると仮定することができますか? (私が知っているのは、それ以外のことを知っているか気にしている唯一のコンパイラです) –
@Martin:何かをする前にBoost 1.46.1または1.47 betaを試してみてください。 1.44.0がほぼ一歳となっていることを考慮すれば、これはすでに修正されている可能性が高いです。 – ildjarn
問題は何ですか?このコードに「厳密なエイリアシング」の問題はありますか? – mattn