Type は、1つか複数のデータ項目を含む、カスタム・データ型を宣言するために使われます。
整数型、浮動小数点型、固定長か可変長(動的)の配列、固定長か可変長の文字列、ビット項目、あるいは他のユーザー定義型を含めることができます。
Type は、オブジェクト指向プログラミングと関係する様々な機能性をサポートします:
Type には、さまざまな種類の入れ子にされた
type や
union(共用体) を含めることができます:
- 入れ子にした匿名の 型/共用体:
- 入れ子にされた匿名の type や union(共用体) により、データ メンバーを必要に応じてグループ化できます。
- 匿名の Type または 匿名の Union は、交互に入れ子にすることを条件に、入れ子にすることができます。
- 入れ子にされた匿名の 型/共用体は、手続きメンバーまたは静的データ メンバーを持つことはできません (Type/Union という名前のローカル スコープと同じ制限)。
- 入れ子にされた名前付き 型/共用体:
- 入れ子にされた名前付き 型/共用体は、(名前付き)Type/Union 名前空間の内側で、場所のアクセス権に従って内部構造を宣言することができます。
- 名前付き型/共用体で実行できるほとんどすべてのことは、ネストされた名前付き型/共用体でも実行できます。
- Type/Union 間に循環依存関係がある場合、入れ子にされた名前付き型/共用体を使うと、型エイリアスの使用や前方参照を回避できます。
- 入れ子にされた型定義:
- Nested Type-Def では、Type/Union の内部で、その場所のアクセス権に応じた内部型(Alias)を宣言することができます。
主構造体(Type または Union)は常に名前を付ける必要があり、他の (入れ子にされた) 構造は無名または名前付きにすることができます。
Alias "alternatename" は、
typename を(オブジェクト・モジュールやライブラリのように)パブリック・シンボルにエンコード(修飾)する必要がある場合、
typename の通常のエンコード(修飾)の代わりに、
alternate 名を使います。
メモリ・レイアウト
Type は、
Type の項目を、メモリに連続的に配置します。固有の整列と詰め物の規則(
Field ページに記述) に従います。
Type を、ファイルI/Oに使う場合や、他のプログラムやプログラミング言語と対話するとき、特別に注意しなければなりません。整列と詰め物の規則が異なることがあるからです。
オプションの
Field = number 指定子を使うと、FreeBASIC 側の振る舞いを変更できます。
可変長データ
FreeBASIC では、型データ構造は、最終的に固定サイズでなければなりません。コンパイラが、どれだけのメモリをその型の対象に割り当てるかわかっている必要があるからです。
それでも、型は可変長(動的)文字列や配列データ・メンバーを含むかもしれません。
しかし、文字列/配列のデータは、型に直接埋められません。
その代わり、
Type は、
String/配列記述構造を含むだけです。
そして、FreeBASIC は、この記述構造を、可変長文字列/配列データを管理するために裏側で使います。
Type (型)の配列記述子の構造をサイズ設定するために、可変長(動的)配列データメンバは、常に配列の範囲のところに
Any(s) を使って宣言する必要があり、指定された Any の数に基づいて次元の量を固定します。
可変長(動的)配列のデータメンバーは、
Redim を使った構文で宣言時にサイズをあらかじめ指定することもできます。
可変長の配列フィールドは、可変長の文字列と同様に、
Type で宣言されると、疑似オブジェクトとみなされます(暗黙のコピー構築子と暗黙の let 演算子自体が、このような配列の[再]サイジングとコピー、およびその消去をサポートします)。
このため、そのような
Type をファイルに保存するには、実際の文字列/配列データではなく、記述子を書きます。
文字列/配列を、
Type に直接埋め込むためには、固定長文字列/配列を使わなければなりません。
同様に、
Type の中でポインターを使って、手で動的なデータを維持するとき、ファイルに
Type を保存することは、通常意味をなしません。ポインターが指す実際のメモリではなく、ポインター項目に格納されるアドレスが、ファイルに書かれるからです。
アドレスは、特定のプロセスにのみ意味があります。そのように共有されることができません。
固定長文字列の特別な注意
fbc バージョン 1.20.0 以降、
String * N 型の固定長文字列フィールドは、末尾に余分な null ターミネータがなくなり、実際に使うのは
N バイトだけなので、型内の QB 文字列と互換性を持つようになりました。
fbc バージョン 1.20.0 より前は、
String * N 型の固定長文字列フィールドには、C 文字列との互換性を保つために末尾に余分な null 終端文字があり、ちょうど
N バイトではなく、実際に
N+1バイトを使うため、型内の QB 文字列と互換性がありませんでした。
考えられる回避策は、フィールドを
As String * (N-1) と宣言することでした。ただし、これは、将来のリリースで null 終端文字が削除されると機能しなくなります。 もう 1 つの方法は、適切なサイズの
Byte か
UByte 配列を使うことです。
bitfields ( fieldname : bits ) の注意
ビット項目は、
Type か
Union(共用体)の内部だけで宣言され、ビット長の数で与えられる、非常に小さなオブジェクトを指定できるようにすることができます。
各項目は、アクセスされて、それが構造体の通常の一員であるかのように操作されます。
整数データ型(32ビット開発では最大32ビット、64ビット開発では最大64ビット)のみ、有効です。
宣言データ型のサイズは、ビットパターンを含むのに十分な大きさで、メモリにビット項目を配置される方法に影響します。
型内のビット項目メンバーは、次のメンバーが非ビット項目でない限り、一緒にパックされます(ネストされたユニオンは非ビット項目と見なされます)。
ビット項目にはアドレスがありません(構造内で、ビット項目へのポインタと、そのオフセットを取得することはできません)。