C言語のポインタ減算

先日色々試していたら、わりと面白い結果が出たのですが、その内容について少し紹介します。
以下、C言語の基礎的な知識を仮定します。

#include
int main()
{
    long* temp;
    printf("%d\n", (temp+1)-(temp));
    return 0;
}

を実行すると、4(=sizeof(long))が出力されるんだと自分は思っていたのですが、実際にコンパイル*1して実行してみると1が出力されます。
しかし、例えば

#include
int main()
{
    long* temp;
    printf("%d\n", (int)(temp+1)-(int)(temp));
    return 0;
}

とすると、期待通りに4が出力されます。ではなぜ前者では1が表示されたのか?ということですが…
自分は当初、コンパイラが(カッコによる優先順位指示を飛び越して!)何らかの最適化を施した結果、temp同士がキャンセルしてしまっているのかと思ったのですが、色々調べてみたところ、どうやら以下のことが原因だったようです。
ポインタを含む減算演算と ptrdiff_t 型変数
すなわち、ポインタ同士の差を取るような場面では、コンパイラが暗黙的にptrdiff_t型へキャストして計算するようです。そして、ptrdiff_t型においては、差を取ったポインタが指していたオブジェクトのサイズを1とするため、先程の例では4ではなく1が出力された…ということだと思われます。


ptrdiff_t型とは…。C99はまだまだ分からないことばかりです。

*1:今回はgcc (GCC) 3.3.6 release (Vine Linux 3.3.6-0vl7を使用しました。