returnはCommitで、throwはReset?

うーん、
returnをすることもthrowをすることも、
実際には上位に対して何らかの状態を伝えるために戻る、ということをするわけで、

bool File::open(const char* path)
{
    if (!FileSystemOpen(&handle_, path)) {
        return false;
    }
    ...
}

はダメで、

bool File::open(const char* path)
{
    if (!FileSystemOpen(&handle_, path)) {
         throw io_error_exception("IOError");
    }
    ...
}

は良い、というのがいまいちわからない……。
例外は例外的な何かを呼び出し元に伝えるためにあるけれど、
戻り値を持つreturnは呼び出し元に戻り値を伝えるためにあるわけで、
別物ではあるけれど、returnはダメでthrowは良い、っていうのは違和感があるかも?
そういうと、gotoはダメでreturnは良いのか、とかあるんですが、うーん。
gotoはJPで、
returnはRETで、
throwはsetjmp,longjmpだということを考えたとき、
最も素直で流れを読みやすいのはreturnだよねえ。
とか思っちゃうのは多分アセンブリ脳。