3

このコードを考えると:

A2.H

_declspec(dllimport) void SomeFunc();

struct Foo
{
  Foo();
  ~Foo();
};

inline Foo::Foo() { }

inline Foo::~Foo()
{
  SomeFunc();
}

A1.H

#include "A2.h"

extern "C" void TriggerIssue(); // <-- This!

extern "C" inline void TriggerIssue()
{
  Foo f; 
}

MyTest.cpp

#include "A1.h"

int main()
{
  return 0;
}

この問題の背景については、こちらを参照してください。

MyTest.cpp が実行可能ファイルにコンパイルされると、リンカーはそれSomeFunc()が未解決の外部であると文句を言います。

これは、A1.h での TriggerIssue の余分な (間違った?) 宣言が原因であると思われます。それをコメントアウトすると、リンカーエラーがなくなります。

誰かがここで何が起こっているのか教えてもらえますか? その宣言の有無でコンパイラの動作が異なる原因を具体的に理解したいだけです。上記のスニペットは、私が遭遇しているシナリオの最小限の検証可能な例を書き込もうとしたものです。なぜそのように書かれているのか、私に聞かないでください。

反対票を投じる方への注意: これは、未解決の外部シンボル エラーを修正する方法に関する質問ではありません。したがって、これを重複として閉じるために投票を停止してください。この質問に「答えがあるかもしれない」と主張しているこの投稿の上部に表示され続けるリンクを削除するのに十分な信用がありません。

4

2 に答える 2

2

SomeFuncはプログラムでODR を使用しているため、定義が使用可能である必要がありますが、(この翻訳単位で、または別の翻訳単位でのリンクによって) 定義が提供されておらず、プログラムには未定義の動作があり、診断は必要ありません™.

リンカーがエラーを返す理由は、コンパイラがTriggerIssue;の定義を生成したためです。余分な宣言の存在に応じて動作が異なることは確かに興味深いことです。少なくとも同じ動作をすることが期待されます。UB はさておき、コンパイラは自由に選択できます。関数は、関数inlineのすべての定義が同一であることを保証しているため、リンク時に重複シンボルがある場合、リンカは単純にそれらを破棄できます。

于 2016-05-30T21:26:26.637 に答える