iOSのlong型に注意

例えば時間計算でよくあるケースとしてエポックから現在時までの経過秒数(GMT)を取得する処理だが、Objective-C/Cocoaでは以下のように簡単に書ける。

NSDate* now = [NSDate date];
long result = (long)([now timeIntervalSince1970] * 1000); //秒数なので1000を乗じる

NSDateクラスのtimeIntervalSince1970メソッドの戻り値はNSTimeIntervalつまりdoubleだが、その後の計算がしやすいようにlongで受けている。 long型は64bitアーキテクチャでのサイズは64bitでありdouble型を格納するには十分のはずだ。

しかし上記コードをコンパイルして実行するとiOSデバイス上では桁あふれを起こしてしまう。実際にはlong long型が必要なのだ。
MacOS Xは64bitカーネルでありlong型も64bitのはずである。 え?64bitじゃないの?

そう。iPhone向けということはARM向けのバイナリなんだからlongは32bitなのである。

iOSの開発のようにビルドしている環境とビルドターゲットが違う場合は注意が必要である。ましてやJavaのようにプラットホームの差異を吸収してくれる層が無いC言語系ではアーキテクチャによって型の大きさが違うのは決して不思議なことではない。

当たり前のことなのだが、ついつい忘れがちだ。