KDOC 208: 宣言と定義の違い
この文書のステータス
- 作成
- 2024-08-03 貴島
- レビュー
- 2024-08-10 貴島
概要
宣言と定義の違いってなんだろうか。
コンパイラが使うか、リンカが使うか
c++ - What is the difference between a definition and a declaration? - Stack Overflowの解説は興味深い。
宣言(declaration)。
A declaration introduces an identifier and describes its type, be it a type, object, or function. A declaration is what the compiler needs to accept references to that identifier.
宣言は識別子を導入し、その型(型、オブジェクト、関数など)を記述する。宣言は、コンパイラがその識別子への参照を受け入れるために必要なものだ。
定義(definition)。
A definition actually instantiates/implements this identifier. It’s what the linker needs in order to link references to those entities.
定義は、実際にこの識別子をインスタンス化/実装する。これは、リンカがこれらのエンティティへの参照をリンクするために必要なものだ。
コンパイラが使うのか、リンカが使うのか、という視点は新鮮だ。
コンパイラに型を伝えるか、メモリを確保するか
宣言と定義の違い | C++ プログラミング解説も見てみる。
名前 (識別子) の型をコンパイラに伝えるのが宣言で、その名前が参照している実体 (メモリ) を確保するのが定義です。
文章は異なるが、これは先に紹介した考え方と整合しているように見える。
確かめる
考え方を、アセンブラで確かめてみる。
↑アセンブル結果に this_is_declaration
は残らず、 this_is_define
だけが残る。「宣言」の内容はコンパイラがコンパイル時にデータ型によってメモリサイズを決定するために使うもので、実行時に必要な情報ではない。なのでアセンブリには現れないといえる。いっぽうで「定義」の内容はメモリに実際の値を保持する。実行時に必要な情報であるのでアセンブリに現れる。
↓関数型でも同じ考え方が成り立つのを確認する。
また、宣言と定義のユースケースの違いに由来する些細な挙動の違いを見る。
↓「宣言」は同じ識別子で複数存在できる(型が違うとtype conflict errorになる)。
↓「定義」は識別子に対してユニークでなければならない。 error: redefinition of 'test'
。
宣言と定義の表記はわずかな違いだが、異なる意味であることを理解できた。
関連
- KDOC 46: Goの宣言構文がCと異なる理由。宣言つながり
- KDOC 141: Cのポインタ操作をアセンブリで見る。アセンブリで確認するシリーズ
- KDOC 205: エラーと例外の違い。使い分けが曖昧なまま使っているコンピュータ用語について考える部分が共通しているため