こんにちは。
C言語に関する質問です。
関数等で複数ファイルをまたいでコンパイルする場合、
makeを用いる方法と、ヘッダーをincludeする方法に
何か違いはあるでしょうか。
makeでコンパイルをする場合、
・mainが書かれてるファイル「main.c」
・ある関数が書かれてるファイル「function.c」
が存在し、それをmake等でつなげてコンパイルすることが基本なのかなと思います。
一方、ヘッダーをincludeする場合、
・mainが書かれてるファイル「main.c」
・ある関数が書かれてるファイル「function.h」(ヘッダー)
とファイルを作成し、
main.cで#include "function.h"を行い、
makeを使わずに単にgcc等でmain.cをコンパイルすることも可能であると思います。
上記二つの書き方は動作は同じかと思っているのですが、
メリット・デメリット等はあるでしょうか。
C言語で複数ファイルをまたぐコンパイルについて(Makefileかヘッダーか)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: C言語で複数ファイルをまたぐコンパイルについて(Makefileかヘッダーか)
makeは単に自動的にビルドを行うためのツールです。実際に結合するのはgccです。
で、前者の場合自分でgccコマンドを書いても同じことが出来ます。自動的に必要なだけの最低限のビルドは出来ませんけどね。
後者のコード全体をヘッダーに書いてしまった場合、必要なだけの最低限のビルドが出来ませんので数百ファイルにも及ぶと一行直すだけで数十分何も出来ない恐ろしいコンパイル時間となります。
と言うことで、前者と後者の違いにmakeは関係なくてgccの動作の違いだけです。
で、前者の場合自分でgccコマンドを書いても同じことが出来ます。自動的に必要なだけの最低限のビルドは出来ませんけどね。
後者のコード全体をヘッダーに書いてしまった場合、必要なだけの最低限のビルドが出来ませんので数百ファイルにも及ぶと一行直すだけで数十分何も出来ない恐ろしいコンパイル時間となります。
と言うことで、前者と後者の違いにmakeは関係なくてgccの動作の違いだけです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: C言語で複数ファイルをまたぐコンパイルについて(Makefileかヘッダーか)
えっと,この話というのは,例えば
という形で2つのソースファイル(.c)に分かれていて,
(1)main.cをコンパイル
(2)function.cをコンパイル
(3) (1)と(2)の結果をリンクしてビルド完了
みたいなことをmakeを使ってやっているときに…
そのようなことをせずに,ソースを
のように書いてしまえば同じことなのではないか? みたいな話なのでしょうか.
確かにこの場合,「プログラムを実行したときの動作(実行結果)」という点では同じと言って良いのかもしれませんが…
「Makefileかヘッダーか」という捉え方は,何か認識を大きく間違っていると思います.
(makeは上記した(1)(2)(3)みたいな手順を(楽に?)行うためのツールであり,
他方,includeというのはソースのコピペ機能ですから,両者は全く違うものです.)
//main.c
int Func(); //プロトタイプ宣言
int main(){ return Func(); }
//function.c
int Func(){ return 1; }
(1)main.cをコンパイル
(2)function.cをコンパイル
(3) (1)と(2)の結果をリンクしてビルド完了
みたいなことをmakeを使ってやっているときに…
そのようなことをせずに,ソースを
//main.c
#include "function.h"
int main(){ return Func(); }
//function.h
int Func(){ return 1; }
確かにこの場合,「プログラムを実行したときの動作(実行結果)」という点では同じと言って良いのかもしれませんが…
「Makefileかヘッダーか」という捉え方は,何か認識を大きく間違っていると思います.
(makeは上記した(1)(2)(3)みたいな手順を(楽に?)行うためのツールであり,
他方,includeというのはソースのコピペ機能ですから,両者は全く違うものです.)
オフトピック
ヘッダファイルの一般的な(?)利用目的は 宣言をコピペすること であり,
後者の方法(ヘッダ内に関数の定義が書かれている)は ヘッダの一般的な使い方から逸脱しています.
「別に一般的じゃなくてもいいし」と,そのやり方を貫き通すのだとしても
例えば,「もう一個のソースファイルでもFunc()を使う場合とかはどうするのでしょう?」とか面倒事だけが付いて回るような気がします.
後者の方法(ヘッダ内に関数の定義が書かれている)は ヘッダの一般的な使い方から逸脱しています.
「別に一般的じゃなくてもいいし」と,そのやり方を貫き通すのだとしても
例えば,「もう一個のソースファイルでもFunc()を使う場合とかはどうするのでしょう?」とか面倒事だけが付いて回るような気がします.