glibc で UINT_MAX が数値リテラルじゃなかった

上の記事はこの辺をいじってて気付いたのだった:

$ echo -e '#include<limits.h>\nUINT_MAX;'|gcc -E - -o -|tail -n3
# 12 "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed/limits.h" 2 3 4
# 2 "<stdin>" 2
(2147483647 * 2U + 1U);

UINT_MAX = 2^32-1 = INT_MAX (= 2^31-1 = 2147483647) * 2 + 1 ということで,定数伝播を期待したマクロ定義になってるぽいんだけど.アホなパーザがリテラルのsemantic valueをint型で返して,INT_MAX を超えた値が壊れるのを恐れてるのかな?
そう言えばAutodesk 3ds Maxというモデラーがあって,それを操作するスクリプト言語 "MAXScript" になぜか私は詳しいのだけど,実際MAXScriptのパーザはアホだったな... JavaScriptみたく値に応じて勝手に 32 bit int か float (doubleだっけ? 忘れた) か,「適切に」切り替わるんだが,INT_MIN 相当の値 (-2147483648) をREPLに打ち込むとfloatになって精度が失われてしまう.ところが INT_MIN+1 相当の値をREPLに打ち込むと,これは32 bit int精度で評価されるので,この値に変数 x を束縛する.その後に x-1 を評価すると,やはりちゃんと32 bit intとして INT_MIN 相当の値が返る.これは想像するに,パーザ(と言うかレクサ)が,例えば -10 を [TOKEN_MINUS, TOKEN_INT(10)] のように処理していて,ここでlexeme TOKEN_INT は内部を32 bit intで管理してるんだろうな.まぁ「forループからのbreakはC++の例外で実装してるから速度を期待しないでね(はぁと)」とか書いてあるような言語だったからな...