FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

継承しているポインタをスマートポインタにするときはshared_ptrを使う

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

...
};
 public:
    InstEnv *m_inst_env;     // Instruction Execution environment
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; }

前回に書いた、サイズの問題と違って、どうやら継承するメンバのポインタを宣言するときは特殊な配慮が必要なようだ。

hightoro.hatenablog.com

shared_ptrを使うことで、うまく処理することができるらしい。早速導入してみると、うまくいった。

github.com

結局やったのは、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));

これでコンパイルできるようになった!