GLib 2が用意している基本的なデータ型について(ページ2/3)
「GLib 2が用意している基本的なデータ型について(ページ1/3)」の続き。
環境によらずbit数/値の範囲を保証する型
GLibが提供する型の中にはbit数を保証する型が存在し、例えばgint64という型はどのアーキテクチャであっても64bitであることが保証される(扱える値の範囲もこれに対応して決まる)。こういった型の定義はGLibの中のアーキテクチャ依存なヘッダファイル/usr/lib(64)/glib-2.0/include/glibconfig.hの中に記述されており、自動的に参照される(手動で取り込んだりする必要はない)。
型の説明 | GLibが用意する型 (範囲) |
---|---|
整数型/符号あり/8bit | gint8 (G_MININT8 - G_MAXINT8) |
整数型/符号なし/8bit (バイト単位の処理に使える) | guint8 (0 - G_MAXUINT8) |
整数型/符号あり/16bit | gint16 (G_MININT16 - G_MAXINT16) |
整数型/符号なし/16bit | guint16 (0 - G_MAXUINT16) |
整数型/符号あり/32bit | gint32 (G_MININT32 - G_MAXINT32) |
整数型/符号なし/32bit | guint32 (0 - G_MAXUINT32) |
整数型/符号あり/64bit | gint64 (G_MININT64 - G_MAXINT64) |
整数型/符号なし/64bit | guint64 (0 - G_MAXUINT64) |
一般的には1バイトに相当するbit数(アルファベットや数字の1文字のコードを表現するのに必要なbit数でlimits.hのCHAR_BITの値)というものは仕様では決まっていないようだが、2010年現在主流となっているPCのアーキテクチャでは1byte=8bitとなっている。
例として、GLibのByte Arrays(日本語訳)という機能もバイト単位のデータはguint8型を用いており、GIOのg_data_output_stream_put_byte()関数ではguchar型を用いている。
printf()系関数のフォーマット文字列指定
bit数の保証されている型をprintf()系関数で扱う場合には、そのフォーマット文字列(printf()の場合は1番目の引数)の「%」の後ろの部分が「G_[型名]_FORMAT」というマクロになっているのでこれを用いる(こうしないと適当に書いた指定で偶然それが動いたとしても環境依存なコードとなってしまう)。
gint64 i = G_MAXINT64; printf ("i = %" G_GINT64_FORMAT "\n", i);
上はgint64型の例だが、guint64型では「G_GUINT64_FORMAT」のように「U」が付く。
具体例なマクロは
http://web.archive.org/web/20080609054222/www.gnome.gr.jp/docs/glib-2.8.x-refs/glib/glib-Miscellaneous-Macros.html
にある。
関連:GLibに動的リンク(実行時に依存)せずにbit数保証の型のみを用いる
GLibを用いて作成したプログラムは実行時にGLibの共有オブジェクトに動的リンクすることになるが、本記事で扱っているような型の定義についてはヘッダファイルの中で完結しているものなので(共有オブジェクトから取り出す必要がない)、上記のようなbit数の保証されるデータ型は欲しいが実行時にGLibに依存したくないという場合でも
- GLibの開発パッケージをインストールする
- 「#include
」をC言語のソースの最初の辺りに記述する - コンパイル時にコマンド行の中に「$(pkg-config --cflags glib-2.0)」をオプションとして含める
という手順のみでこうした型を利用しつつ実行時にGLibに依存しない実行ファイルが作成できる。
下は例。
[任意]ファイル名: gint64test.c
/* * GLibに実行時に依存せずにbit数の保証される型を用いる(GLibの開発パッケージは必要) * 注意点としては、GLibの関数を用いないようにする * * gcc -O2 -Wall -Wextra $(pkg-config --cflags glib-2.0) gint64test.c -o gint64test */ #include <stdlib.h> #include <stdio.h> #include <glib.h> int main () { gint64 i = G_MAXINT64; printf ("i = %" G_GINT64_FORMAT "\n", i); return EXIT_SUCCESS; }
実行結果はアーキテクチャによらず下のようになる。
i = 9223372036854775807
これはCライブラリのみに依存する実行ファイルとなる。
$ objdump -p [gint64testの場所] | grep NEEDED NEEDED libc.so.6
(「GLib 2が用意している基本的なデータ型について(ページ3/3)」に続く)
関連記事:
参考URL:
- http://web.archive.org/web/20080222233546/www.gnome.gr.jp/docs/glib-2.8.x-refs/glib/glib-Basic-Types.html - GLibが提供する型について/バージョン2.8系日本語訳
- http://library.gnome.org/devel/glib/stable/glib-Basic-Types.html - GLibが提供する型について/最新安定版(英語)
- http://web.archive.org/web/20080322030231/www.gnome.gr.jp/docs/glib-2.8.x-refs/glib/glib-Limits-of-Basic-Types.html - 型ごとの値の上下限/バージョン2.8系日本語訳
- http://library.gnome.org/devel/glib/stable/glib-Limits-of-Basic-Types.html - 型ごとの値の上下限/最新安定版(英語)
- http://web.archive.org/web/20080609054222/www.gnome.gr.jp/docs/glib-2.8.x-refs/glib/glib-Miscellaneous-Macros.html - G_GINT64_FORMATなどのマクロの定義/バージョン2.8系日本語訳