ISSの中でどうしてもunique_ptrに変更できないものがあった。それがInstEnvクラスだ。InstEnvクラスは、MIPS用とRISC-V用で両方ビルドするために、ベースクラスであるEnvBaseでpublic領域に宣言されており、それを継承したMipsEnvもしくはRiscvEnvにて実際にインスタンスを作成する仕組みになっている。
- env.cpp
class EnvBase { ... public: std::shared_ptr<InstEnv> m_inst_env; // Instruction Execution environment ... };
- mips_env.h
public: InstEnv *m_inst_env; // Instruction Execution environment
- mips_env.cpp
MipsEnv::MipsEnv (FILE *dbgfp, FILE *uart_fp, bool en_stop_sim, bool is_debug_trace) : EnvBase (is_debug_trace) { SetDbgFilePointer (dbgfp); m_inst_env = new InstEnv (this);
そうすると、以下のようなエラーメッセージが出てコンパイルに失敗した。
Scanning dependencies of target swimmer_mips make[2]: Leaving directory '/home/vagrant/swimmer_mips/build_mips' make -f CMakeFiles/swimmer_mips.dir/build.make CMakeFiles/swimmer_mips.dir/build make[2]: Entering directory '/home/vagrant/swimmer_mips/build_mips' [ 4%] Building CXX object CMakeFiles/swimmer_mips.dir/home/vagrant/swimmer_mips/src/swimmer_main.cpp.o /usr/bin/c++ -DARCH_MIPS -O0 -g -Wall -fdiagnostics-color -g -I/home/vagrant/swimmer_mips/build_mips/../vendor/gflags/include -I/home/vagrant/swimmer_mips/ build_mips/. -std=c++0x -o CMakeFiles/swimmer_mips.dir/home/vagrant/swimmer_mips/src/swimmer_main.cpp.o -c /home/vagrant/swimmer_mips/src/swimmer_main.cpp In file included from /home/vagrant/swimmer_mips/src/./mips_env.h:33:0, from /home/vagrant/swimmer_mips/src/swimmer_main.cpp:34: /home/vagrant/swimmer_mips/src/././env.h: In member function ‘InstEnv* EnvBase::GetInstEnv()’: /home/vagrant/swimmer_mips/src/././env.h:148:41: error: cannot convert ‘std::unique_ptr<InstEnv>’ to ‘InstEnv*’ in return InstEnv *GetInstEnv (void) { return m_inst_env; }
前回に書いた、サイズの問題と違って、どうやら継承するメンバのポインタを宣言するときは特殊な配慮が必要なようだ。
shared_ptrを使うことで、うまく処理することができるらしい。早速導入してみると、うまくいった。
結局やったのは、unique_ptrではなく、shared_ptrを使っただけだ。
MipsEnv::MipsEnv (FILE *dbgfp, FILE *uart_fp, bool en_stop_sim, bool is_debug_trace) : EnvBase (is_debug_trace) { SetDbgFilePointer (dbgfp); m_inst_env = std::shared_ptr<InstEnv>(new InstEnv (this));
これでコンパイルできるようになった!