16

C ++では、関数または変数を匿名の名前空間に配置すると、そのリンケージが内部になります。つまり、staticファイルレベルで宣言するのと同じですが、慣用的なC++です。

通常の名前空間内の匿名の名前空間はどうですか?それでも内部リンクは保証されますか?

// foo.cpp

void func1() {
    // external linkage
}

static void func2() {
    // internal linkage
}

namespace {
    void func3() {
        // internal linkage
    }
}

namespace ns1 {
    void func4() {
        // external linkage
    }

    namespace {
        void func3() {
            // still internal linkage?
        }
    }
}
4

3 に答える 3

15

匿名の名前空間内のエンティティが内部リンクを持っているとは限りません。それらは実際には外部リンケージを持っているかもしれません。

名前のない名前空間は、それがコンパイルされた翻訳単位に固有の名前を持っているため、リンケージが何であるかに関係なく、その翻訳単位の外部から宣言されたエンティティを参照することはできません。

C ++標準によると(C ++ 03 7.3.1.1 / note 82):

名前のない名前空間内のエンティティには外部リンケージがある場合がありますが、それらは翻訳ユニットに固有の名前で効果的に修飾されているため、他の翻訳ユニットからは見えません。

于 2010-11-15T02:57:34.327 に答える
13

C ++ 11(ドラフトN3337)§3.5/ 4 :(強調鉱山)

名前のない名前空間、または名前のない名前空間内で直接または間接的に宣言された名前空間には、内部リンケージがあります。他のすべての名前空間には外部リンケージがあります。上記の内部リンケージが与えられていない名前空間スコープを持つ名前は、それがの名前である場合、それを囲む名前空間と同じリンケージを持ちます。

- 変数; また

- 機能; また

—名前付きクラス(第9節)、またはtypedef宣言で定義された名前なしクラス。クラスはリンケージの目的でtypedef名を持ちます(7.1.3)。また

—名前付き列挙型(7.2)、またはtypedef宣言で定義された名前なし列挙型で、リンクの目的で列挙型にtypedef名が付いている(7.1.3)。また

—リンケージのある列挙に属する列挙子。また

—テンプレート。

これにより、名前のない名前空間には内部リンクがあることが保証されます。

通常の名前空間内の匿名の名前空間はどうですか?それでも内部リンクは保証されますか?

名前付き(通常)名前空間内にありますが、名前なし(匿名)名前空間であるため、C++11標準に従って内部リンクを持つことが保証されています。


関数または変数を匿名の名前空間に配置すると、そのリンケージが内部になります。つまり、ファイルレベルで静的であると宣言するのと同じですが、慣用的なC++です。

C ++ 11ではstatic、このコンテキストでの使用は非推奨ではありませんでした。名前のない名前空間は、の優れた代替手段staticですが、失敗する場合がstaticあり、これは;によって修正されます。これに対処するためinline namespaceにC++11で導入されました。

于 2013-10-21T18:20:41.470 に答える
5

$ 3.5 / 3-「名前空間スコープ(3.3.6)を持つ名前は、

—明示的に静的と宣言されている変数、関数、または関数テンプレート。また、

— constとして明示的に宣言されており、externとして明示的に宣言されておらず、外部リンケージを持つように以前に宣言されていない変数。また

—匿名ユニオンのデータメンバー。

したがって、プログラム内の「func3」および「func4」という名前のいずれかに内部リンクがあるかどうかは疑問です。それらは外部リンケージを持っています。ただし、ジェームズの引用によると、他の翻訳ユニットからは参照できないというだけです。

于 2010-11-15T03:13:06.717 に答える