gccの-lオプションが効かない時があるのでその原因を確かめてみた。
$ gcc pp4.c pp.c pp2.c /tmp/ccj9EogJ.o: In function `func': pp2.c:(.text+0x7): undefined reference to `link2' /tmp/cchGaury.o: In function `main': pp.c:(.text+0x11): undefined reference to `link1' collect2: ld はステータス 1 で終了しました こんなソースがある場合、link1とlink2を含むlibpp3.soで解決する必要がある 当初、ソース1個以上指定した後の-lオプションのみが有効かと思いきや リンクメッセージがないと-lが効かないという話を教えてもらったので試してみた。 $ gcc pp4.c -l pp3 pp.c pp2.c /tmp/ccj9EogJ.o: In function `func': pp2.c:(.text+0x7): undefined reference to `link2' /tmp/cchGaury.o: In function `main': pp.c:(.text+0x11): undefined reference to `link1' collect2: ld はステータス 1 で終了しました あら、ほんとだ。pp4.cはlink1もlink2も依存していないため これでもエラーが起こる・・・。 $ gcc pp4.c pp.c -l pp3 pp2.c では、link1に依存するpp.cの後に-l pp3を移動させると エラーはなくなった~ てっきり /tmp/ccj9EogJ.o: In function `func': pp2.c:(.text+0x7): undefined reference to `link2'みたいなのが出ると思ったのだけどそうでもないらしい。 つまり・・・ -lオプションは最後に書けということですなぁ。 バージョンによっては直ってるgccもあるらしい。 PR |
なぜ、coutのほうが遅いのか?
どうやら double型が特に遅いみたいである。 で、かくかくしかじか辿っていった結果。 一因がnum_putクラスが遅いことが分かった。 num_putのdo_putオーバーライド
localeにnum_putを追加
●実行方法1~3で計測してみることにした。 実行方法1
実行方法2
実行方法3
結果(ms)
情報整理 ・num_putが遅いことには間違いない。 ・coutは doubleを置換する場合、try catchを行っている。 ・coutのostream の出力方法は4×nバイト または1バイトのみである。 ・coutのostreambufの出力方法はnバイト または1バイトのみである。 ・coutのnum_putの出力対象はchar型のiter_typeなので出力方法は1バイトのみである。 ・coutはostreambufでバッファを抽象化し、osteramで循環キューを抽象化している。 結論 coutまわりはクラスが立て込んでいて、ostreambufにフォーマッタがあればいいが フォーマッタはostreamはlocaleに散らばっている。 これらはostreamが使うワーク領域がostearmbufが管理するワーク領域が 異なっていることに起因しているのかもしれない。 ただし、num_putの中身がどうなっているのか未確認のため怪しい。 また、printf系はバッファを素直にI/Oにしているため FILEポインタのみを通しているのに対し、writerと媒体の距離が近いのに対し cout系はostreamからnum_putを経てostreambufの間を1バイトずつ細切れで渡していってる模様。 writerとバッファの距離は遠そうなイメージ? そんなこんなで、よっぽど最適化されるようにならないと 関数を読んでるだけのprintf系に追いつくのは厳しいと思われる。 きっとjavaの初期のころってこういう課題をなんとかインラインになるように 頑張ったんだろうなと。 しかし、C++の場合はジェネリックはテンプレート頼みだし coutなんて標準ライブラリだからインラインにする前に コンパイル済みの関数に紐づくんじゃないかなぁと。 |
私が思う構造化プログラミングとは、順次・選択・繰り返しにおいて
状態遷移がきちんと定義されていること。 これを理解できてないプログラマは多いと思う。 ある特定の条件の時だけ値を返すマイルールを コメントに書かないで平気だとほんと困る。 ●非構造化プログラミング
●構造化プログラミング
|
結局のところ平行四辺形かまるっとした四角形かの違いになるのかな。 アップルが嫌った時のgccも今はやり方が変わっているし 今のコンパイラならもう少し違っていたかもしれない。 Perl5とPerl6くらい違うイメージかな。 個人的にはSSAとCPSとの再会ってすごくおもしろいと思う。 Clangとgccも再会することは・・ ライセンスの壁は厚いし無理か(笑 |
忍者ブログ [PR] |