typedef

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

typedef(タイプデフ)は、プログラミング言語CC++キーワードである。これはデータ型に新しい名前(エイリアスシノニム)をつけるために使用される。プログラマが容易にソースコードを理解できるようにすることが目的である。

使用例[編集]

一つのコード例:

int coxes;
int jaffa;
...
coxes++;
...
if (jaffa == 10)
...

別のコード例:

typedef int Apples;
typedef int Oranges;
Apples coxes;
Oranges jaffa;
...
coxes++;
...
if (jaffa == 10)
...

両方のコードの処理内容は同じである。2つ目の例でtypedefを使ったことで、何が行われているかを容易に理解することが出来る。すなわち、一つの変数はリンゴ(Apples)に関する情報を含み、もう一つの変数がオレンジ(Oranges)に関する情報を含んでいることがわかる。

別のコード例:

struct var {
    int data1;
    int data2;
    char data3;
};

ここでは、ユーザ定義の型varが定義されている。var型の変数を作るために、C言語では以下のコードが必要である:

struct var a;

この例の最後に、以下の行を追加してみる:

typedef struct var newtype;

これにより、var型の変数を作るためには、以下のコードで十分となる:

newtype a;

同じことは、以下のコードでも行うことができる:

typedef struct var {
    int data1;
    int data2;
    char data3;
}newtype;

typedefは、自己参照構造体へのポインタの作成を簡単にすることも出来る。以下にコード例を示す:

struct Node{
int a; //Data
struct Node *nextptr;
};

通常、ポインタに割り当てるそれぞれの変数の前にアスタリスクを記述する必要がある:

Node *startptr, *endptr, *curptr, *prevptr, errptr, *refptr;

プログラマはerrptrがポインタ型Node *であることを想定しているが、Typoによりerrptrは値型Nodeであると定義されてしまっている。これは微妙な構文エラーを引き起こす。

Node *型を定義することは、より良いことである。以下のコードがその例である:

typedef Node *NodePtr;
...
NodePtr startptr, endptr, curptr, prevptr, errptr, refptr;

これにより、errptrを含めて全ての変数がNode *型であることが保証される。


C++の構造体宣言では、潜在的にtypedefが定義される。つまり、typedefキーワードを明示的に使わなくとも、データ型は直ちに(struct varではなく)varで指定することができる。

C++ではクラス内部でtypedefを使用することで、クラス スコープのシノニムを定義することができるため、テンプレートを使用したジェネリックプログラミングダックタイピングに都合がよい。C++標準ライブラリのSTLの実装では、このテクニックが利用されている。


批判[編集]

一部の人々は、typedefを広範に使用することに反対している。ほとんどの議論は、typedefは単に変数の実際のデータ型を隠すだけであるという考えに集中する。例えば、Linuxカーネルハッカーであり、ドキュメント作成を行っているグレッグ・クロー=ハートマン(Greg Kroah-Hartman)は、関数プロトタイプ宣言を除いて、typedefの使用をやめさせようとしている。彼は、typedefを使用することが、必要以上にコードを混乱させるだけでなく、プログラマが巨大な構造体を単純な型と誤認識して使用してしまうことがあると主張している[1]

しかし、typedefを推奨して、広範に使用することに大賛成する人々もいる。特に、C言語を発明したブライアン・カーニハン (Brian W. Kernighan) とデニス・リッチー (Dennis M. Ritchie)はプログラミング言語C(英:The C Programming Language)というC言語の定義書に、typedefの利用に対するメリットを2つ述べている。まず第一は、多プラットフォームにとって、ポータビリティ性を相当に向上させる手段として重要なことである。データ形の改良が必要になるときに、必要な変更はただ1つだけのtypedefの宣言箇所であり、typedefシノニムを利用してさえいれば多くの箇所を変更する必要がなくなる。第二に、データを隠すことに加えて、データのカプセル化も向上させるようになり、複雑な宣言がより理解しやすくなることである。もともとC言語の規格では、基本型(intなどの組込型)のサイズを厳密に規定しておらず、処理系依存となっている(ターゲット プラットフォームにとって都合の良いサイズに設定してよいことになっている)ため、プラットフォーム間の違いを吸収して同じソースコードを使うためにはtypedefは必須の技術といえる(Windowsの例でいうと、Win16Win32におけるint型の違い、Win32Win64におけるポインタ型の違いなど)。


他の言語[編集]

HaskellMirandaObjective Caml等のような、多くの静的型付けの関数型言語では、C言語でのtypedefと同じ働きをする、type synonymを定義することが出来る。Haskellでの例:

type pairOfInts = (Int, Int)

これにより、Intのペアと同じものをtype synonymの"pairOfInts"で定義することができる。


PascalおよびObject Pascalではtypeキーワードを使用することで、typedef同様に別名を定義することができる。

type
    TMyInt = Integer; // 組込型Integerに対するシノニム。


C/C++の特徴を取り入れたC#言語では、基本型のサイズは厳密に決められており、またtypedefは言語機能として存在しないが、代わりにusingエイリアス ディレクティブ機能が存在する。

using MyString = System.String;


関連項目[編集]

参照[編集]

  1. ^ Kroah-Hartman, Greg (2002年7月1日). “Proper Linux Kernel Coding Style”. Linux Journal. 2007年9月23日閲覧。 “Using a typedef only hides the real type of a variable.”

外部リンク[編集]