1. ホーム
  2. c

[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて

2022-02-08 05:15:09

質問

3つのプロジェクトがあります。 サーバー , クライアント コモンズ . のヘッダーとソースのペアを作成します。 コモンズ の両方から自由にアクセスすることができます。 サーバー クライアント .

しかし、何らかの理由で、追加のソース/ヘッダーファイルを サーバー または クライアント プロジェクトは常に multiple definition of (...)first defined here のエラーが発生します。

commands.h (のルートディレクトリにあります)。 クライアント プロジェクト)

#ifndef COMMANDS_H_
#define COMMANDS_H_

#include "commands.c"

void f123();

#endif /* COMMANDS_H_ */

コマンド.c (のルートディレクトリにあります)。 クライアント プロジェクト)

void f123(){

}

main.c (のルートディレクトリにあります)。 クライアント プロジェクト)

#include "commands.h"
int main(int argc, char** argv){

}

エラーです。

make: *** [Client] Error 1      Client
first defined here              Client
multiple definition of `f123'   commands.c

クリーニング、インデックスの再構築、プロジェクトの再構築を行っても解決しない。コンピュータを再起動してもダメです。

解決方法は?

ここで問題なのは、あなたが commands.ccommands.h を関数プロトタイプの前に置く。そのため、C言語のプリプロセッサは commands.ccommands.h を関数プロトタイプの前に置く。 commands.c には関数定義が含まれています。 その結果、関数定義が関数宣言より前に来てしまい、エラーが発生します。

の内容は commands.h プリプロセッサーフェーズの後では、次のようになります。

#ifndef COMMANDS_H_
#define COMMANDS_H_

// function definition
void f123(){

}

// function declaration
void f123();

#endif /* COMMANDS_H_ */

C言語では、関数を定義した後で宣言することはできないので、これはエラーになります。 #include "commands.c" というのも、関数プロトタイプが関数宣言の前に来るようになったからです。

しかし .c ファイルは バッドプラクティス であり、避けるべきである。この問題に対するより良い解決策は commands.hcommands.c で、コンパイルされたバージョンのコマンドをメインファイルにリンクします。例えば

commands.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif

コマンド.c

#include "commands.h"

void f123(){} // function definition