3

externを使用してC++でAdaにインターフェイスしようとしています。これら2つの実装の違いは何ですか?

実装A

namespace Ada
{
    extern "C"
    {
        int getNumber();
        int index;
        int value;
    }
}

実装B

namespace Ada
{
    extern "C"
    {
        int getNumber();
    }
    extern "C" int index;
    extern "C" int value;
}

どちらの実装も問題なくコンパイルされます。しかし、Impl-Aはリンクに失敗し、インデックスの複数定義エラーが発生します。私は違いを理解しようとしているだけです。

4

3 に答える 3

7

extern "C"は、extern"C"ブロック内のコードに使用するリンク規則のみを伝達します。そのブロック内のすべてのものは、純粋なcであるかのようにリンクされます。紛らわしいことに、externintはまったく異なります。これは、インデックスという名前の実際のintと値という名前の実際のintがどこかにあることを約束していることを意味しますが、これらはここでは見つかりません。あなたの実装では-Aintは実際には第2の意味でexternではありません-extern"C"は、厳密なcリンク規則を提供することを意味するだけです。

同じキーワードですが、使用法がまったく異なります。これは、このような奇妙な問題につながるため、残念です。それらを混合することは(明らかに)合法ですが、それらの名前が示すように一緒に動作しません。

編集

C ++標準で定義されている外部の奇妙さの真の定義については、Charleの応答を参照してください。

于 2010-09-03T20:04:07.017 に答える
7

ブレースで囲まれた宣言のシーケンスに適用されるリンケージ指定子extern "C"またはextern "C++")は、囲まれた宣言が定義であるかどうかには影響しませんが、単一の宣言に適用されるリンケージextern指定子は、宣言も定義です。(C ++ 03の7.5パラ7)

それで:

extern "C" { int a; } // a is declared and defined

extern "C" int a; // a is just a declaration (as if extern int a;)

extern "C" int a = 0; // a is a definition because of the initializer.
于 2010-09-03T20:17:28.990 に答える
3

2番目が機能する理由はわかりませんが、

namespace Ada
{
    extern "C"
    {
        int getNumber();
        extern int index;
        extern int value;
    }
}

宣言 indexしたいだけでvalue定義したくないからです。(違いについては、この回答を参照してください。)

于 2010-09-03T19:49:55.360 に答える