undefined reference to memcpy

UINT foo[40] = { 0 };

なんてやると,memcpyが無いという身に覚えの無いエラーを受ける.

初期化する領域が長いとき,GCC*1はmemsetやmemcpyを使って速度最適化を図る*2.しかし,言うまでもなくfreestanding環境ではmemsetの存在が期待できないため,この最適化は行ってはならない.
しかし,いくつかのバージョンのGCCは,この最適化を抑止することができない*3.残念ながらPizzaFactoryが使っているGCC3.4系は,この地雷をモロに踏んでいる.

このバグは割と有名なようで,例えば,Bruce Evans氏がバグなんじゃねぇの?と言ったりもしている.

既に本家での開発が終了したGCC3.4系は,誰かが直してくれるという期待はできない.まあ私が直すわけですが.

ちなみに最も安直な逃げ方は,下記の通り.

static UINT foo[40] = { 0 };

静的変数の初期化はmemsetでは行えないため,GCCは最適化を諦める.

*1:バージョンに依存する.PizzaFactoryの現在のGCCは3.4.x系

*2:どれくらいの長さの時に最適化するかというのは,ターゲットやGCCのバージョンに依存

*3:-ffreestanding など明示的にオプションを指定しても回避できない