どこかのだれかへ

ボク、プログラマ。

ヘッダーファイルではnamespace内でもusing指令は書いちゃダメ

仕事のプログラムを見ていたら、ヘッダーのnamespace内にusing namespace XXXを書いている人がいました。ヘッダーファイルにusing指令を書くのは御法度です。しかしusing指令はブロックスコープなので、もしやこれは大丈夫なのかな?と思い、以下のような実験コードを試してみました。

namespace A
{
    void FuncA(){}
}

namespace B
{
    using namespace A;

    void FuncB()
    {
        FuncA(); // OK
    }
}

namespace B
{
    void FuncB2()
    {
        FuncA(); // OK Oh...
    }
}

希望としては"using namespace A"はB::FuncB2()には効かないとうれしかったんですが使えてしまうようで、別ブロック同名前空間が汚染されていることが確認できました。つまりこんなコードが書かれたヘッダーファイルをインクルードしてしまうと、それ以降は汚染されてしまうので、ヘッダーファイルにこのようなコードを書くのはNGとなります。これが出来るとclassメンバー変数とか書くのが楽になるなぁと思っていましたが、甘くはないようです。

プロジェクトによってはビルド時間短縮のためにcppファイル内で複数のcppファイルをincludeしてオブジェクトファイル数を減らす、なんて手法があったりするんですが、そうなったらcpp側の実装にもusing指令の汚染が広がってしまい、なかなかきついことになってしまいます。

やってから知りましたが、そもそも名前空間スコープとブロックスコープは扱いが全然違うようです。CppReference.comで仕様を確認しましたが、そこにも「名前空間スコープとブロックスコープに有効」と書いてありました。

仕事の方は・・・・・・現状汚染がひどいので「この名前空間内ではusing指令効いているよ!」を仕様にするのが早いと感じています。すでに汚染が広がっているのに動いているし、接頭辞ルールがあって切り分けできているので、たぶん大丈夫なはず、と信じたいです。