ページ 11

C言語で複数ファイルをまたぐコンパイルについて(Makefileかヘッダーか)

Posted: 2014年10月09日(木) 13:16
by len
こんにちは。
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をコンパイルすることも可能であると思います。

上記二つの書き方は動作は同じかと思っているのですが、
メリット・デメリット等はあるでしょうか。

Re: C言語で複数ファイルをまたぐコンパイルについて(Makefileかヘッダーか)

Posted: 2014年10月09日(木) 13:35
by softya(ソフト屋)
makeは単に自動的にビルドを行うためのツールです。実際に結合するのはgccです。
で、前者の場合自分でgccコマンドを書いても同じことが出来ます。自動的に必要なだけの最低限のビルドは出来ませんけどね。
後者のコード全体をヘッダーに書いてしまった場合、必要なだけの最低限のビルドが出来ませんので数百ファイルにも及ぶと一行直すだけで数十分何も出来ない恐ろしいコンパイル時間となります。
と言うことで、前者と後者の違いにmakeは関係なくてgccの動作の違いだけです。

Re: C言語で複数ファイルをまたぐコンパイルについて(Makefileかヘッダーか)

Posted: 2014年10月09日(木) 16:24
by usao
えっと,この話というのは,例えば

コード:

//main.c
int Func();  //プロトタイプ宣言
int main(){  return Func();  }

//function.c
int Func(){  return 1;  }
という形で2つのソースファイル(.c)に分かれていて,
(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()を使う場合とかはどうするのでしょう?」とか面倒事だけが付いて回るような気がします.