2008-09-08

SQLITE_INT_TO_PTR(X)

SQLite 3.6.2をLLVM-GCC 4.2でコンパイルすると、整数からポインタへのキャストが定数値でないというエラーが発生する。LLVM-GCC固有の問題なのか、GCC 4.2の問題なのかは知らない。正確に言うと問題ですらない。

sqlite3.c: In function 'sqlite3RegisterDateTimeFunctions':
sqlite3.c:11837: error: initializer element is not constant
sqlite3.c:11837: error: (near initialization for 'aDateTimeFuncs[0].pUserData')

コンパイル時定数でない値を配列の初期化に使用していると不平を述べている。

  • sqlite/src/sqliteInt.h
    • FuncDef構造体の配列を用いてSQL関数を表現する。
    • FuncDef構造体を作成するためにFUNCTIONマクロを定義する。
    • FUNCTIONマクロはSQLITE_INT_TO_PTRマクロを利用して整数をvoid*に変換する。

かつて整数とポインタは同義だったかもしれない。そんな昔のことは憶えていないし、そんな先のことは判らない。

#define SQLITE_INT_TO_PTR(X)   ((void*)&((char*)0)[X])
#define SQLITE_PTR_TO_INT(X)   ((int)(((char*)X)-(char*)0))

コンパイル時定数にするかどうかはコンパイラの自由なので、SQLITE_INT_TO_PTR(X)はコンパイル時定数にならないかもしれない。SQLiteの名誉のために付け加えると、配列の初期化に使用している箇所ではX0から3までのリテラルだ(SQLITE_OMIT_DATETIME_FUNCSマクロが定義されていない限り)。宗教論争に加わるには人生は短すぎる。整数が何ビットだろうと、ポインタが何ビットだろうと、はたまた関数ポインタが何ビットだろうと知ったこっちゃない。

#define SQLITE_INT_TO_PTR(X)   ((void*)(X))

0 件のコメント: