C/C++のヘッダーファイルは何のために存在しているのでしょうか?用途としての意味は関数やクラスの定義をヘッダーファイルでしていて他のファイルからinculdeできるというのは存じているのですが、最近のプログラミング言語ではヘッダーファイルを書く必要がないのでなぜC/C++では必要なのかといった疑問から質問した所存です。
推測としては当時はコンパイラーがそこまで賢くなっかったため、定義をヘッダーファイルとして書かないと動作しなかったが現在のコンパイラーはそこら辺をうまくやってくれていると思うのですが、どうなのでしょうか?
また、現在のヘッダーファイルを記述しなくていい言語もコンパイラーが内部的にヘッダーファイルを作成しているのでしょうか?
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/21 21:07
2021/05/21 22:16
回答7件
0
ベストアンサー
C/C++ が古い言語だからという理由に落ち着くんだろうと思います。
なぜそう言えるかと言うと、新しい言語でその方式が採用されていないからです。
インクルードは確かに強力で柔軟な機能ですが、強力で柔軟すぎてデバッグを難しくすることがあります。
そこで最近の言語では、型やシグネチャの情報をテキストで読み込むのではなく、ユーザーから隠蔽して提供しています。
インクルードした場合、それはテキストとしてソースファイルの一部になってしまうため、デバッガでそれ以上の追跡ができません。
ユーザーから隠蔽して提供される場合、型情報はソースではなく紛れもない型情報として提供できるため、ツール側の負担が小さくなります。
また、ヘッダをプログラマが書かなければならないということは、同じことを二度書かなければならないことを意味し、どちらかの更新をもう片方と同期させることが人間の責任になってしまいます。ここは自動化できる部分なので自動化するのが望ましいと考える人が多かったのでしょう。
型情報やマクロ定義がごちゃ混ぜになっているヘッダは人間にとっても負担が大きいということです。
投稿2021/05/21 22:35
編集2021/05/21 22:50総合スコア28669
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
イマドキであれば、潤沢なメモリ領域、強大なCPUパワー、というのを前提として言語設計というのができます
どれだけソースファイルの数があろうと、usingやimportでそのファイルを指定すれば、そいつの言語解析を行い、使うことのできるキーワードのデータベースを作り、何ごともなくコードのコンパイルをしてくれます。
さて、メモリが数十キロバイト(MとかGじゃないよ)、クロック周波数が2MHzの8ビットCPUという環境で、そういう事ができるのかということを考えてみましょう。あるいは、どれだけのことができるのかを考えてみるのがいいかと思います
C言語というのはそういう環境の時代のものです
投稿2021/05/21 23:07
総合スコア88042
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
出遅れてしまいましたが、歴史的なことを知って置いて欲しいので投稿します。
C/C++のヘッダーファイルは何のために存在しているのでしょうか?
分割コンパイルやライブラリ利用の際に発生するインタフェースエラーをコンパイル時に検出するためです。
インタフェースエラーの検出は大きく分けると、コンパイル時、リンク時、実行時の3通りになります。プログラム開発ではなるべく初期の段階でエラーを検出したいという要求があります。
コンパイラは文法の責任は持ちますが、ユーザが定義したソースファイルや第三者が提供したライブラリの情報は持っていません。コンパイラが知り得ないソース情報の整合性をコンパイル時にチェックする方法の一つが変数の型や関数の型の宣言を格納したヘッダーファイルです。
歴史的に見ると、1954年に開発されたFORTRANには、当初は分割コンパイルとという概念はありませんでした。ライブラリもなく、必要な機能はコンパイラに組み込まれた文や関数だけしか使えませんでした、1959年に開発されたCOBOLや1964年に開発されたBASICも同じような感じだったと思います。
その後、ファイルを分割して分割コンパイルとリンクという概念が出てきましたが、変数の型や関数の引数や型を合わせるのはプログラマの責任でした。
1970年開発のPASCALや1072年開発のCは、宣言によって変数の型や関数の引数や型の不整合をコンパイル時にチェックできるようにしました。
これに代わる方法としては、プロジェクトファイルなどでソースを管理するとか、インターネットにライブラリ情報を置いておいてそれを読み込むとか、リンク時に型情報をチェックするとかいろいろな方法があるでしょう。
投稿2021/05/22 01:41
総合スコア24670
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
「賢い」という言葉が適切かどうかとは思いますが、C言語が開発された1970年代に思いを馳せてみると...今と比べて格段に
・遅いCPU
・少ないメモリ
・容量小さく遅いストレージ
で処理されていたわけです。その制限下でどうやってそこそこのサイズのプログラム群を処理するか...答え「人海戦術」。
そもそものC言語のソースの構造を考えてみてください。あるソースで注目している時点に登場するシンボルは、そのシンボルに意味を与える宣言か、既に宣言された(あるいは予約語)もののみ、です。コンパイラは、既に知っているシンボルだけを処理すればいいようになっていますね(関数は宣言を仮定しちゃうという荒業もありますが)。そのほうがコンパイラの作りが簡単になるでしょう。で、宣言が先に出てくるように気を遣うのは「プログラマの責任」ということにすれば万事解決。それがCのポリシーなんだから、同意できない奴は使うな、ということで。
では、ファイル分割した他のファイルのシンボルはどうやって知りましょう? ストレージはこんなに小さくてアクセスが遅くて、メモリはこんなに狭いのに、コンピュータがすべてのファイルを解析してシンボルのリストを作る? いやぁ、大変だから、そういうのもプログラマに丸投げ。プログラマが、他のファイルの情報を切り出して宣言を集めたヘッダファイルを作ってください。本質としてヘッダファイルの情報ってのは定義のあるソースファイルと全く重複しているんですけど、プログラマは神なんだから世界の有り様は全部管理して。必要なヘッダの取り込みなんてのもプログラマが指示してね。
つまり、(当時の)コンピュータがやるのが大変そうなところを人間が手作業でやることにしたのが「ヘッダファイル」というシステムなんだ、と勝手に理解しています。
先にそういうシステムができてしまえば、後付で利点を探す動きもあるでしょうけど...やっぱりそんなのは本来人間がやる仕事じゃなかったわけで、他の回答にもあるように、最近の言語では分割したファイルの中身にまで関わる情報を人間が管理するなんてことはもうあり得ないでしょう。
Cって原始的、ですよね。
Cを学ぶとコンピュータのことがよくわかります! ですか? そうでしょう。今どきならコンピュータがやればいいようなことも人間が肩代わりするんですから。
投稿2021/05/21 23:27
総合スコア7703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
一部私の私見が混ざっていますが
C/C++の世界では宣言と定義の区別が大きいからだと思います。このため、宣言部をヘッダとして独立化させる意義が大きいです。宣言だけであれば(矛盾ない範囲で)重複することができるので多重インクルードを気にせず利用できます。例えば、グローバル変数は名前空間(定義が適用される範囲)が広く、一箇所で使用されただけで他の部分に影響を与える可能性があります。
例えばjavaの場合では事実上、定義は宣言を兼ねており区別が不要です。また、パッケージの概念のおかげで、名前空間が分割されます。
投稿2021/05/21 21:48
総合スコア4830
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/21 23:01 編集
2021/05/21 22:34
2021/05/21 22:55
退会済みユーザー
2021/05/25 00:46 編集
0
なぜ、C, C++にヘッダーファイルがあるかと言うとC, C++を設計した人が便利だと思って作ったから。
なぜ、最近の言語にヘッダーファイルがないかと言うと「なんでヘッダーファイル書かなきゃならんの?めんどくさい。」と思った人が多かったからなくなった。
それだけのことです。
もうちょっと補足します。
C言語の設計者が作った機能は #include という非常に便利な機能だけです。
これは例えば次のような使い方も出来ます。(コンパイル実行確認済)
HelloAnotherDimensionOfTheWorld.txt
txt
1void HelloAnotherDimensionOfTheWorld() 2{ 3 std::cout << "Hello Another dimension of the World!\n"; 4}
HelloAnotherDimensionOfTheWorld.cpp
C++
1#include <iostream> 2#include "HelloAnotherDimensionOfTheWorld.txt" 3 4int main() 5{ 6 HelloAnotherDimensionOfTheWorld(); 7 8 return 0; 9}
これを曲解した利用者が、まず#includeするのは拡張子".h"のファイルだけにしましょうというルールから始まって、様々なルールで縛り付けて使いにくくした結果「ヘッダーファイル書くのめんどくさくね?」って意見が多数を占めるようになり、#include という非常に便利な機能も闇に葬られたわけです。
早くも2つも低評価が付いていますが、まぁ#include の機能の便利さを曲解して様々なルールで縛り付けて使いにくくしている代表者のような方々でしょう。C言語と言うものは本来非常に緩いルールで自由に書けるものです。
投稿2021/05/21 23:03
編集2021/05/22 00:19退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/22 00:15
退会済みユーザー
2021/05/22 00:22
2021/05/22 00:23 編集
2021/05/22 00:35 編集
退会済みユーザー
2021/05/22 00:25
2021/05/22 00:34
2021/05/22 00:39
退会済みユーザー
2021/05/22 01:11
2021/05/22 01:19
退会済みユーザー
2021/05/22 03:44 編集
2021/05/22 04:25
2021/05/22 04:28
2021/05/22 04:38
退会済みユーザー
2021/05/22 05:31
退会済みユーザー
2021/05/22 05:32
2021/05/22 05:32
退会済みユーザー
2021/05/22 05:35
2021/05/22 05:42
退会済みユーザー
2021/05/22 05:45
退会済みユーザー
2021/05/22 05:51
2021/05/22 05:52
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。