同じ構造体Aを使用する2つの翻訳単位がある場合は、通常、その構造体をヘッダーに配置します。 e。プリプロセッサに両方のTUに定義をペーストさせます。リンカーは、2つの構造体定義が等しくないことを無視できますか?
私たちはそれをしないとしましょう。異なる定義を使用することが許されていますか?どうして?
createA.c:
typedef struct {
int data;
} A;
A createA() {
A a = {10};
return a;
}
のmain.c:
#include <stdio.h>
typedef struct {
int value;
float x;
} A;
A createA();
int main(int argc, char *argv[])
{
A a = createA();
printf("value is %d, x is %f\n", a.value, a.x);
a.x = 3.1f;
printf("value is %d, x is %f\n", a.value, a.x);
}
VS 10 2つの構造体のサイズが異なっていても、喜んで一緒にこれをリンクするように見えます。つまり、createA
へのコールは、2つのTU(スタックの変更が異なる)で異なって動作します。これは少し奇妙です。関数に引数を追加すると、実行時にプログラムがクラッシュしますが、リンカーエラーは発生しません。
これはなぜ興味深いのですか?私は、impl* impl_data
の代わりにunsigned char impl_data[impl_size]
のようなものをパブリックヘッダに使用し、インプリメンテーションファイルの実際のインプストラクチャにキャストするPimplのバリアントにこのメカニズムを使用することができないのかどうか疑問に思っていました。実践的な考慮事項(例えば、impl_sizeの決定など)は許可されていますか?
構造体の定義が複数あることは、コードのコピー貼り付けをしたい人のための壮大なデバッグセッションです。 1つの場所が、別の場所はありません)。すべてのコンパイラの安全チェックをバイパスし、リンカに依存します。それらは私の孫に伝えたい私のお気に入りのバグです。 – Drop
@Drop Yep、[楽しいように聞こえる](https://stackoverflow.com/questions/4339697/type-checking-across-source-files) –