• 締切済み

G++ 例外は要らない

G++ 4.4を使ってプログラミングをしています。 オブジェクトサイズを出来るだけ削りたいので、例外処理に関するコード量を減らせないかと画策しています。 -fno-exceptionsを指定してみたのですが、あまり効果はありませんでした。 objdumpしてみると.eh_frameセクションがかなり大きく、まずはこれが削れたらいいなと思うのですが、調べても方法が見つかりませんでした。 とりあえず、C++の機能として  ○クラス  ○仮想関数  ○多重継承  ○テンプレート は使いたいです。なのでCで書き直すのはNGです。 一方、必要のない機能は  ○例外処理  ○標準C++ライブラリ です。 もしかすると、G++自体をビルドする段階で--disable-exceptionsを指定してビルドしておかないと無理なんでしょうか?現状ではG++を再ビルドすることは困難です。 よろしくお願いいたします。

みんなの回答

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

せめてどのオブジェクトファイルで.eh_frameが大きいのかぐらいは特定してください。 ターゲットがarm-elfの場合でも、普通、.eh_frameは4バイト程度にしかならないはずです。.gcc_except_tableの間違いではないでしょうか? なお、libgccはC言語でも使うランタイムですので、これがないとまともに動きません。libstdc++も、例えば純粋仮想関数を間違って呼び出したときに走る処理とかもあったはずですので不可欠かと思います。 どうも後だし条件が多すぎる気がします。 他に出していない重要な情報はもうありませんか?

haniriito
質問者

お礼

たびたびのコメント、恐れ入ります。 > せめてどのオブジェクトファイルで.eh_frameが大きいのかぐらいは特定してください。 どのオブジェクトファイルが・・・ということはありません。ソースコードが長いときはeh_frameも相応に大きくなり、一番小さいもので(ソースコードで20行程度、Cソース[C++ではない])48バイト、大きいものでは6324バイトもありました。確認方法はobjdump -hでセクション情報を抜き出して.eh_frameの'SIZE'に該当するところを見ました。 .eh_frameセクションのサイズ確認方法としては合っていますよね? 試しにしょうもないコード int test() { return 5; } とかだけのコードをtest.cというファイルに書いて、  arm-elf-gcc -c -g test.c でコンパイルすると、それだけで.eh_frameは48バイトになっています。 eh_frameってC++の例外処理に関する情報が入るのですよね?純粋なC-onlyなコードなのになぜ・・・? > libstdc++も、例えば純粋仮想関数を間違って呼び出したときに走る処理とかもあったはずですので不可欠かと思います。 g++4では"__cxa_pure_virtualなんたら・・・"とかいう関数ですよね。今回はそういう処理すら不要なので、自前でこの関数を定義してsystem haltさせるようにします。それでもlibstdc++は不可欠ですか? > 他に出していない重要な情報はもうありませんか? 別に出し惜しみをしているわけでもなく何が重要な情報なのか分からないだけなのですが、 大げさに言ってしまうとC++ライブラリだけでなく、Cの標準ライブラリの機能すら必要ありません。C++コンパイラのクラスや継承、仮想関数という"仕組み"と実行コードだけが欲しくて、スタートアップルーチンやoperator newなどのランタイム環境などはすべて自前で用意しますので、サイズが大きくてゴタゴタした余計なものはリンクして欲しくないのです。その一つとして目を付けたのが「例外処理」ということなんです。

haniriito
質問者

補足

結果報告の意味を含め、「お礼」よりも後になりますが「補足」にて報告します。 YAGARTOのarm-elf-gcc4.4.1を使うと、-gオプションを付けるだけでなぜかeh_frameセクションが生成され、そこに何らかの情報(例外フレーム情報か?、内容を逆アセすると実行コードではなく何かのデータ)が生成されていました。不思議なことに-fno-exceptionsをつけてもつけなくても-gオプションがある限り生成され、コード量に応じて増えていきました。YAGARTOのビルドオプションでそうなっているのでしょうか・・・。 YAGARTOではなく、codesourcery-armの2009q3を使う(arm-none-eabi-gcc 4.4.1)と-gオプションがあってもeh_frameは生成されず、オブジェクトコードが想定通りに減りました。更に、stdc++ライブラリもリンクせずに済むようになったので、更に実行コードを減らすことができるようになりました。 最後になりますが、「もっと情報はないか?」ということなのでいろいろ考えて情報を出したつもりですが、その後コメントを何の反応もいただけず非常に残念に思います。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

g++のconfigureオプションを補足してください(g++ -vで出力されるないようです)。 あと、可能な範囲で、確認に使ったソースも補足してください。 -fno-exceptionsは、それを指定した翻訳単位にしか適用されません。ライブラリなど、事前にコンパイル済みのものは対象外だと考えてください。 operator newなど、例外が絡むものは少なからずありますので、標準C++ライブラリを使わなければ済むというものではありません。

haniriito
質問者

お礼

アドバイスありがとうございます。 > -fno-exceptionsは、それを指定した翻訳単位にしか適用されません。 その点は理解しております。 それと一点言い忘れておりましたが、今回は組み込み系ということで「標準入出力」も不要で使っていないので、ご指摘の点も含めて考えると余計なライブラリはリンクしたくないのですが、リンク時にlibgccやlibstdc++はリンクしておかないと大量の未定義シンボルが報告されてしまいます。やはり、gccが用意するc++のランタイム環境はある程度libgccなどに頼らざるを得ないのかな、と考えています。 > operator newなど、例外が絡むものは少なからずありますので、標準C++ライブラリを使わなければ済むというものではありません。 ご指摘ありがとうございます。 繰り返しになりますが、今回は組み込み系なので、operator newやoperator new[]自体も自前のものに置き換えて、例外を発生させないようにしています。staticなクラスインスタンスのコンストラクタを呼び出すコードさえ自前で実装しているくらいです。 あとは、new演算子で例外が発生することを想定したコードをコンパイラが生成しないようになれば例外フレーム情報の増大を(ある程度)防げると考えたのですが、それをコンパイラに指示するオプションが無さそうです。 他に何かお気づきの点がありましたら、よろしくお願いいたします。

haniriito
質問者

補足

まずは補足として、configureオプションの内容を付けます。 今回のtargetはARMでクロスコンパイラということになります。 Target: arm-elf Configured with: ../gcc-4.4.1/configure --target=arm-elf --prefix=/home/yagarto/install --disable-nls --disable-shared --disable-threads --with-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --enable-languages=c,c++ --enable-interwork --enable-multilib --with-newlib --with-headers=../newlib-1.17.0/newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp -v Thread model: single gcc version 4.4.1 (GCC) ソースはちょっとすぐには用意できないです。システムコール関係やoperator new関係は自前のものを用意しているので、ここに乗せるにはかなり大きくなってしまいます。

関連するQ&A