5

動的ライブラリに既に存在する関数を再定義しても、コンパイルおよびリンク エラーがスローされないのはなぜですか?

以下の関数で

#include "calc_mean.h"
#include <stdio.h>

int mean(int t, int v) {
  return 0;
}

int main () {
  int theMean = mean(3,6);
  printf("\n  %d\n",theMean);
}

共有ライブラリ内 平均関数の定義は、以下のように既に存在します。

#include <stdio.h>
#include "calc_mean.h"

int mean(int a, int b) {
  return (a+b)/2;
}

mean 関数の定義は共有ライブラリに既に存在しますlibmean.so。しかし、コンパイル中に再定義エラーは表示されず、コンパイルは成功しました。

そして、実行が成功すると、私が見るo / pは4ではなく0であるため、共有ライブラリ内の平均の関数定義は実行されませんが、メインモジュール内の関数定義は実行されます。

どうしてこうなった?

4

3 に答える 3

1

1 つの外部から見える関数の 2 つの定義があると (非インライン関数の定義が同一であっても)、未定義の動作が発生し、診断は必要ありません。(参照: C99 6.9#5 および附属書 J.2)

C では、不正なコードによってコンパイラの診断が必要なものと、そうでないものがあります。通常、診断を必要としない理由は次のとおりです。

  • すべてのコンパイラにエラーの検出と報告を要求するのは、法外すぎると考えられます。
  • それを診断しない既存のシステムが使用されており、標準委員会は既存の実装を不適合にすることを望んでいませんでした。

この場合、私の推測では、これは最初のケースです。彼らは、コンパイラ/リンカーが弱いシンボルを拡張機能として実装するオプションを開いたままにしたかったため、コンパイラがここで警告を出す必要があることを指定しませんでした。あるいは、これを一般的に検出するのは実際には難しいかもしれません。リンカーを作成しようとしたことはありません。

診断が行われない場合は、実装の品質の問題と見なす必要があります。おそらく、リンカーに別のフラグを渡して、このコードを拒否することができます。そうでない場合は、バグレポートまたは機能リクエストを送信できます。

于 2014-06-25T07:43:33.797 に答える