web-dev-qa-db-ja.com

Cプログラミングでは、コンパイル時の「未定義の参照」エラーとは何ですか?

私はLinux ubuntuでコンパイルしようとしている次の簡単なプログラムを持っています。

Main.c

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

int main()
{   
    struct Person1 p1 = Person1_Constructor(10, 1000);
}

Person.c

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

struct Person1 Person1_Constructor(const int age, const int salary)
{
    struct Person1 p;
    p.age = age;
    p.salary = salary;
    return p;
};

Person.h

struct Person1
{
    int age, salary;
};
struct Person1 Person1_Constructor(const int age, const int salary);

次のerrorが表示されるのはなぜですか?

/tmp/ccCGDJ1k.o: In function `main':
Main.c:(.text+0x2a): undefined reference to `Person1_Constructor'
collect2: error: ld returned 1 exit status

使っています gcc Main.c -o Main コンパイルします。

7
dimitris93

プログラムをリンクするときは、Main.oとPerson.oの両方を入力として指定する必要があります。

ビルドは通常、(1)コンパイルと(2)リンクという2つのステップで行われます。ソースをコンパイルするには:

$ gcc -c -o Main.o Main.c
$ gcc -c -o Person.o Person.c

または1行で:

$ gcc -c Main.c Person.c

次に、結果のオブジェクトファイルを単一の実行可能ファイルにリンクする必要があります。

$ gcc -o Main Main.o Person.o

あなたのようないくつかのコンパイルユニットの小さなプロジェクトの場合、両方のステップを1つのgcc呼び出しで実行できます。

$ gcc -o Main Main.c Person.c

Person.cの一部の記号はMain.cによって使用されるため、両方のファイルを指定する必要があります。

より大きなプロジェクトの場合、2つのステップのプロセスにより、実行可能ファイルの生成中に変更されたもののみをコンパイルできます。通常、これはMakefileを通じて行われます。

4
Diego

Main.cMain.cを同時にコンパイルする必要があるときにPerson.cのみをコンパイルしているため、問題が発生している可能性があります。 gcc Main.c Person.c -o MyProgramとしてコンパイルしてみてください。

複数のファイルがある場合は、ここでのように、外部参照を解決するために、コンパイル時にそれらすべてを指定する必要があります。コンパイラは、後で実行可能ファイルにリンクされるオブジェクトファイルを吐き出します。 makefileに関するこのチュートリアルを確認してください。 Make File Tutorial このプロセスを自動化するのに役立ちます。

1
Mlagma