コンパイラ指示子の使用

4D - Documentation   French   English   German   Spanish   日本語   4D v11 SQLコマンドテーマリスト   4D v11 SQLインデックス   4D v11 SQL定数テーマリスト   戻る   前   次

version 2003 (Modified)


変数のデータ型


4Dの変数には次の3種類があります:

・ローカル変数

・プロセス変数

・インタープロセス変数

変数の詳細な性質については変数の節を参照してください。プロセス変数とインタープロセス変数はコンパイラにとって構造的に同じです。

プロセスにどの変数が使用されるか、コンパイラは知ることができないので、プロセス変数の使用にはインタープロセス変数よりも注意が必要です。新規プロセスの開始時にすべてのプロセス変数は複製されます。プロセス変数はプロセスごとに個別の値を持つことができますが、型はデータベース全体を通して同じです。

変数の型

すべての変数には型があります。データタイプの節に記述されているとおり、変数には以下12の異なる型があります:

ブール

固定長文字列

日付

整数

倍長整数

グラフ

時間

ピクチャ

数値 (または実数)

ポインタ

テキスト

BLOB

配列には9の型があります:

ブール配列

文字列配列

日付配列

整数配列

倍長整数配列

ピクチャ配列

実数配列

ポインタ配列

テキスト配列

シンボルテーブルの作成

インタプリタモードでは、変数は2つ以上のデータタイプを持つことが可能です。これは、コードをコンパイルするのではなく解釈するためです。4Dはそれぞれのステートメントを別々に解釈し、そのコンテキストを理解します。しかしコンパイルモードの場合は状況が異なります。インタプリタが一行ずつ実行処理するのに対して、コンパイルの際はデータベース全体を処理します。

コンパイラの処理方法は以下のとおりです:

・コンパイラはデータベース内のオブジェクトをシステマチックに解析します。ここでいうオブジェクトとはデータベース、プロジェクト、フォーム、トリガ、オブジェクトメソッドです。

・コンパイラはオブジェクトを調べ、データベース内で使われる各変数のデータ型を決定し、変数やメソッドのテーブル(シンボルテーブル)を生成します。

・すべての変数のデータ型が確定すると、コンパイラはデータベースの翻訳(コンパイル)を行います。ただし、各変数のデータ型が確定できなければデータベースをコンパイルすることはできません。

同じ変数名で異なる2つのデータ型が見つかった場合、どちらか1つが優先して採用されることはありません。オブジェクトの型を設定してメモリアドレスを割り当てるために、コンパイラはオブジェクトについての名前やデータ型などを正確に認識する必要があります。コンパイラはデータ型からそのサイズを判断します。コンパイルされたデータベースごとにマップが作られ、各変数の名前(もしくは識別子)、場所(もしくはメモリアドレス)、変数が占める容量(データタイプによってわかるもの)を記録します。このマップをシンボルテーブルと呼びます。環境設定のオプションでコンパイル時にこのテーブルをファイル形式で作成するかどうかを選ぶことができます。

このマップは、コンパイラメソッドの自動生成にも使用されます。

変数の型設定

コンパイラは変数の判別基準を守り、以下の方法で型を設定します。

・ 変数の型が設定されていない場合、自動的にコンパイラが代わりにタイプを設定します。曖昧でない場合は可能な限り、使用目的から変数型を設定します。

例えば:

   V1 := True

コンパイラは変数V1をブール型と決定します。

同様に次のように書くと:

   V2:= "This is a sample phrase"

コンパイラは変数V2をテキスト型と決定します。

また、上の例ほど明確でない場合でも、コンパイラは以下のように変数のデータ型を設定することができます:

   V3:= V1   `V3はV1と同じ型
   V4:= 2*V2   `V4はV2と同じ型

また、4Dのコマンドやメソッドに対する呼び出しからも、コンパイラは変数のデータ型を決定します。例えばブール型と日付型の引数をメソッドに渡した場合、コンパイラは呼び出されたローカル変数$1および$2にブール型と日付型を割り当てます。

推測からデータ型が決定される場合、環境設定で指定されていない限りは整数、倍長整数、文字列のような制限のあるデータ型が割り当てられることはありません。デフォルトとして常に最も広範囲な型が割り当てられます。例えば:

   Number:=4

と記述した場合、ここでは4が整数であっても他の状況では4.5になる可能性もあるので、Numberには実数型が割り当てられます。

変数の型を整数、倍長整数または文字列にする場合は、コンパイラ指示子を使います。これらのデータ型はメモリ占有率が少ないため、処理速度が早くなります。

すでに変数型を設定済みで、定義の整合性も完全であると確信した場合、コンパイラの環境設定を使用して、コンパイラに型の自動決定を行わないようコンパイラに指示することができます。定義が徹底されておらず、不完全な場合、コンパイル終了時にエラーメッセージが表示され、必要な変更を行うよう求められます。

・コンパイラ指示子を使用すると、データベースで使用される変数の型を明示的に定義できます。

使用方法は次の通りです:

   C_BOOLEAN(Var)

このような指示子を通じて、コンパイラにブール型の変数を作成するよう通知できます。

アプリケーションでコンパイラコマンドが使用されていれば、コンパイラが型を推測するという作業をしなくて済みます。

コンパイラ指示子は、代入や用途から得られた結果より優先されます。

コンパイラ指示子C_INTEGERで定義した変数は、実際にはC_LONGINTで定義したものと同じです。これらは実際には、-2147483648から+2147483647までの倍長整数です。

どのような時にコンパイラ指示子を使うか


コンパイラ指示子は以下の場合、有用です:

・ コンパイラで前後関係から変数のデータ型を決定できない場合

・ 使用目的から型を決定させたくない場合。

またコンパイラコマンドを使用するとコンパイル時間を短縮できます。

曖昧な場合

コンパイラで変数型を決定できないこともあります。このような場合、コンパイラからはエラーメッセージが出力されます。

コンパイラでデータ型を決定できない場合は、主に3つの原因があります。データ型が複数ある場合、コンパイラの推測した型があいまいな場合、そして型を判断する情報がない場合です。

・データ型が複数の場合

データベース中、異なるステートメントで変数の型が変更されていると、コンパイラはエラーを生成します。

コンパイラは最初に見つけた変数を選択し、そのデータ型を同じ名前の変数の次のオカレンスに適用します。しかしその変数の型が異なるとエラーになります。

例題:

メソッドA,

   Variable:=True 

メソッドB,

   Variable:="The moon is green"

メソッドAがメソッドBよりも先にコンパイルされると、コンパイラはステートメントVariable:="The moon is green"でデータ型が変更されていると判断します。コンパイラは型の変更が行われていることを通知し、エラーを生成します。ほとんどの場合、2番目の変数のオカレンスの名前を変更することで、問題を解決できます。

・コンパイラが決定した型が曖昧な場合

コンパイラが、オブジェクトの型が正しい方ではないと推定することがあります。この場合、コンパイラ指示子を使用して、変数の型を明示的に指定する必要があります。

以下はアクティブオブジェクト用のデフォルト値を使用した例です。

フォーム内で、プロパティリストのデータソーステーマ内にあるデフォルト値用の編集ボタンを使用して、コンボボックス、ポップアップメニュー、タブコントロール、ドロップダウンリスト、メニュー/ドロップダウンリスト、およびスクロールエリアのデフォルト値を割り当てることができます(詳細は4D Design Referenceを参照)。デフォルト値は、オブジェクト名と同じ名前の配列に自動でロードされます。

オブジェクトをメソッド内で使用しない場合、コンパイラはその配列を曖昧さなくテキスト配列と推測できます。

しかし初期化を行わなければならない場合、次のようにコーディングされることがあります:

   Case of
      : (Form event=On Load)
         MyPopUp:=2
         ...
   End case

この場合、曖昧さが出現します。メソッドを解析する際、コンパイラはオブジェクトMyPopUpを実数型と推定します。この場合、フォームメソッドまたはコンパイラメソッドで、配列を明示的に宣言する必要があります:

   Case of
      : (Form event=On Load)
         ARRAY TEXT(MyPopUp;2)
         MyPopUp:=2
         ...
   End case

・型を判断する決め手がない場合

宣言なしに変数が使用されていて、前後関係からデータ型を決定できないような状況です。この場合、コンパイラにとっての決め手はコンパイラ指示子しかありません。

こうした状況は、主に次の4つのコンテキストにおいて起こります:

・ ポインタを使用する場合

・ 複数のシンタックスを持つコマンドを使用する場合

・ 異なるデータ型のオプション引数を受け入れるコマンドを使用する場合

・ URL経由で呼び出された4Dメソッドを使用する場合

- ポインタ

ポインタは、自分自身以外のデータ型を返すことができません。

次のような場合:

   Var1:=5.2         (1)
   Pointer:=->Var1   (2)
   Var2:=Pointer->   (3)

(2) でPointerによりポイントされている変数の型が定義されているにもかかわらず、Var2の型を知ることはできません。コンパイル中、コンパイラはポインタを認識できますが、ポインタが指す変数の型を知る方法はありません。結果、Var2に型を推定できません。このような場合、コンパイラ指示子が必要です:\ C_REAL(Var2).

- 複数シンタックスコマンド

Year of関数に割り当てられた変数を使用する際、この関数の動作に基づき、変数の型は日付しかありえません。しかしことは常にそのように単純とは限りません。たとえば:

GET FIELD PROPERTIES コマンドは2つのシンタックスを受け入れます:

GET FIELD PROPERTIES(tableNo;fieldNo;type;length;index)

GET FIELD PROPERTIES(fieldPointer;type;length;index)

複数シンタックスコマンドを使用する際、コンパイラは選択されたシンタックスや引数を推測できません。データベースのどこかでその使用に基づく型付けが行われていない限り、コンパイラ指示子を使用して変数を型付けしなければなりません。

- 異なるデータ型のオプション引数を受け入れるコマンド

異なるデータ型の複数のオプション引数を受け入れるコマンドを使用する場合、コンパイラはどのオプション引数が使用されたか知ることができません。例えば:

GET LIST ITEM コマンドは2つのオプション引数を受け入れます; 1番目は倍長整数で2番目はブールです。

コマンドは以下のいずれかの方法で使用されます:

GET LIST ITEM(list;itemPos;itemRef;itemText;sublist;expanded)

または:

GET LIST ITEM(list;itemPos;itemRef;itemText;expanded)

データベースのどこかでその使用に基づく型付けが行われていない限り、コンパイラ指示子を使用して変数を型付けしなければなりません。

- URLで呼ばれるメソッド

URLから呼ばれる必要のある4Dメソッドを書くときで、メソッドで$1を使用しないとき、以下のように明示的に$1をテキスト変数として宣言しなければなりません:

C_TEXT($1)

実際コンパイラは4DがURLから呼ばれるかどうか判断できません。

コンパイルの時間の短縮

データベースで使用する変数がすべて明示的に定義されていれば、コンパイラで型定義を調べる必要はありません。この場合、オプションを設定してメソッドの翻訳フェーズだけを行うように指定できます。この操作により、コンパイル時間を半分以下に短縮できます。

コードの最適化

コンパイラコマンドを使用することで、メソッドの処理速度を上げることができます。この件についての詳細は最適化のヒントの節を参照してください。簡単な例として、カウンタとして使用するローカル変数をインクリメントする必要があるとします。倍長整数として宣言すると、コンパイルしたデータベースの効率が良くなります。例えばWindowsの場合、実数データがメモリを8バイト使用するのに対し、倍長整数にすると、4バイトしか使用しません。8バイトのカウンタをインクリメントする場合は当然、4バイトの場合より時間がかかります。

コンパイラ指示子をどこに記述するか


コンパイラ指示子は、コンパイラに変数の型付けをまかせるかどうかによって以下2通りに処理方法が異なります。

コンパイラで型定義される変数

コンパイルで変数型を調べたりまた型定義を行ったりする場合は、簡単にコンパイラコマンドの記述場所を決めることができます。作業方法に応じて以下のいずれかの方法を選んでください:

・ ローカル変数、プロセス変数、インタープロセス変数に応じて、変数が初めて使用されるメソッドやオブジェクトメソッドでコンパイラ指示子を使用します。コンパイラ指示子は、必ず変数が初めて使われる場所、つまり一番初めに実行されるはずのメソッドで使用するようにしてください。コンパイル時、コンパイラは4Dで作成した順序でメソッドを処理します。エクスプローラで表示される順番ではない点に注意してください。

・ コンパイラ指示子で定義するプロセス変数とインタープロセス変数は、On Startup データベースメソッドまたはOn Startup データベースメソッドから呼び出されるメソッドにまとめます。

ローカル変数については、使用するメソッドの一番初めにコンパイラ指示子をまとめてください。

開発者が型定義する変数

コンパイラに型定義をチェックさせたくない場合、コンパイラ指示子を識別できるようなコードをコンパイラに与える必要があります。

これを行う方法は以下です:

プロセス変数、インタープロセス変数についてのコンパイラ指示子および引数を、名前の先頭がキーワードCompilerで始まる1個あるいは複数個のメソッドに記述します。デフォルトで、コンパイラに5種類のコンパイラメソッドを自動生成させ、変数、配列、メソッド引数ごとに命令をまとめることができます(詳細はDesign Referenceマニュアルを参照)。

Note: 引数定義のためのシンタックスは次のとおりです:

Directive (methodName;parameter). このシンタックスはインタプリタモードで実行することはできません。

特別な引数

データベースメソッドが受け取る引数

これらの引数が明確に定義されていなければ、コンパイラが型を決定します。定義する場合は、そのデータベースメソッド内で行わなければなりません。この引数定義をCompilerメソッド内に記述することはできません。

例:On Web Connectionは6つのテキスト引数$1から$6までを受け取ります。データベースメソッドの最初に、C_TEXT($1;$2;$3;$4;$5;$6)を記述する必要があります。

トリガ

トリガの結果である引数$0(倍長整数)は、引数が明確に定義されていなければ、コンパイラが型を決定します。定義する場合は、トリガ自身の中で行う必要があります。

この引数定義は、Compilerメソッド内には記述できません。

"On Drag Over"フォームイベントを受け入れるオブジェクト

"On Drag OVer"フォームイベントの結果である引数$0(倍長整数)は、引数が明確に定義されていなければ、コンパイラが型を決定します。定義する場合は、オブジェクトメソッドの中で行う必要があります。

この引数定義は、Compilerメソッド内には記述できません。

Note: コンパイラは引数$0を初期化しません。したがって、On Drag Overフォームイベントを使用したら、直ちに"$0"を初期化しなければなりません。例えば:

   C_LONGINT($0)
   If (Form event=On Drag Over)
      $0:=0
      ...
      If ($DataType=Is Picture)
         $0:=-1
      End if
      ...
   End if

C_STRING コンパイラ指示子

C_STRING コマンドは、最長文字列数を表す引数も受け入れるため、他の指示子とは異なるシンタックスが使われます。

C_STRING(length;var1{;var2;…;varN})

C_STRINGは固定長文字列を扱うので、文字列の最大の長さを指定する必要があります。コンパイルされたデータベースでは、変数ではなく定数を使用して文字列の長さを指定しなければなりません。

例えば、インタプリタでは、以下のシーケンスを使用できます。

   TheLength:=15
   C_STRING(TheLength;TheString)

4DはTheLengthを解釈し、C_STRINGコンパイラ指示子で、TheLengthをその値に置き換えます。

しかしコンパイラは、変数の型を決定する際代入式を考慮に入れずにこのコマンドを使用します。したがって、TheLengthの値が15であることはわかりません。文字列の長さがわからなくては、シンボルテーブルにその文字列用のスペースを確保できません。文字列の長さを定義する際はコンパイルを念頭において定数を使用する必要があります。例えば、ステートメントをこのように使用します:

   C_STRING(15;TheString)

同じルールがコマンドを使用して固定長文字列配列を定義する際にも適用されます:

   ARRAY STRING(length;arrayName;size)

文字列長を示す引数は定数でなければなりません。

ただし、文字列の長さを、これらのコンパイラ指示子で4D定数または16進法定数を使用して指定することはできます:

   C_STRING(4DConstant;TheString)
   ARRAY STRING(4DConstant;TheArray;2)
   C_STRING(0x000A;TheString)
   ARRAY STRING(0x000A;TheArray;2)

文字フィールドの長さ(最大80文字まで)と、固定長文字変数を混同しないでください。C_STRING指示子、またはARRAY STRINGで定義できる文字列のサイズは1から255までです。

Note: このコマンドのシンタックスでは、同じ長さの変数を1行で複数定義できます。異なる長さの文字列を複数定義する場合は、別の行で行います。

型の矛盾として見なされない場合

コンパイラ指示子によって、曖昧なデータ型や文字の長さは除外されます。特定の厳密さは要求されますが、コンパイラが全ての不一致を受け入れないというわけではありません。

例えば、整数と定義した変数に実数値を代入する、あるいは10文字の文字列として定義した変数に30文字の文字列を代入すると、コンパイラはこれを型の不一致と見なさず、コンパイラ指示子に応じた値を代入します。以下のように記述した場合:

   C_INTEGER(vInteger)
   vInteger:=2.5

コンパイラはこれを型の矛盾としては扱わず、したがってコンパイルは可能です。そして代わりに数値の小数部分を切り上げます(2.5ではなくて3になります)。

同様に文字列の場合、代入しようとした文字数より、宣言した文字数が短い場合、宣言された文字数だけが代入され、残りは削除されます。

次は、文字列処理の例です:

   C_STRING(10;MyString)
   MyString:="It is a beautiful day"

コンパイラは文字列定数の最初の10文字、"It is a be"だけを代入します。

参照

エラーメッセージ, シンタックスの詳細, 型設定ガイド, 最適化のヒント.


4D - Documentation   French   English   German   Spanish   日本語   4D v11 SQLコマンドテーマリスト   4D v11 SQLインデックス   4D v11 SQL定数テーマリスト   戻る   前   次