好き勝手に・げーあにん?

ファミコンと同い年の社会人ヌルオタの日記

gcc (g++) のオプション見直し中

プロジェクトの谷間で時間に余裕があるので、make ファイルを1から書き直し中。make は捨てて、rake に乗り換えてみた。‥‥という話しは、置いといて、gcc のオプションを見直してて思ったことを垂れ流し。

gcc のオプションはFreeBSD 日本語マニュアル検索で見てます。英語の man gcc とか見てると泣きそうになるから(ダメプログラマー)。

-Wall をつけない場合ってどんな時?

ちょっと前に、デストラクタに virtual をつけるつけないかの話しが一部で盛り上がっていた(?)気がしたけど、g++ -Wall とかしてたら、警告で教えてくれるよね。

class Super
{
public:
  ~Super() {} // こいつを virtual にすれば警告でない
  virtual int getA() const;
};

class Sub : public Super
{
};

g++ -Wall -c -o sample.o sample.cpp
sample.cpp:2: warning: `class Super' has virtual functions but non-virtual destructor
sample.cpp:9: warning: `class Sub' has virtual functions but non-virtual destructor

一個でも virtual なメソッドがあって、デストラクタが virtual になってなかったら、"gcc に怒られるからつける"というダメグラマーの習慣なのであった。結果オーライどんなもんだい。

-Wextra (-W)

-W で唯一、うざいと思っていた警告があったんだけど、オプションで消せたのか。知らんかった。

int main()
{
  int i = 0;
  int a[10];
  if (i >= 0 && i < sizeof(a)/sizeof(a[0])) {
  }
  return 0;
}

g++ -Wall -Wextra -c -o sample.o sample.cpp
sample.cpp: In function `int main()':
sample.cpp:5: warning: comparison between signed and unsigned integer expressions
g++ -o sample sample.o

-Wno-sign-compare つけると消える

g++ -Wall -Wextra -Wno-sign-compare -c -o sample.o sample.cpp
g++ -o sample sample.o

うわーい。とか、ぬか喜びしてると、他のところでミスったりするかなぁ。そもそも配列アクセスとかで singned 使うなってことなんだろうなーとは思いつつも。

-Wall 以外の -W 系見直し

-Wall -W 以外は使うと宗教戦争を起こしそうで使ったこと無かったけど、ひとりで書き換えてるうちにコッソリ仕込んどこう。

自分コーディングルールでの仕分け。あくまでわたし用ですからね?

使うもの / 使っても困らなさそうなもの
  • -Wextra
  • -Wpointer-arith
  • -Wcast-qual
  • -Wcast-align
  • -Woverlength-strings
使われると困るもの
  • -Wshadow
  • -Wunreachable-code
迷うもの
  • -Wfloat-equal
  • -Wundef
  • -Wno-div-by-zero
  • -Wlarger-than-
  • -Werror
  • -Wold-style-cast
  • -Woverloaded-virtual
どうなるのかが調べるのがめんどくさいもの(コラ)
  • -Wc++-compat
  • -Wwrite-strings
  • -Wconversion
  • -Waggregate-return
  • -Wnormalized
  • -Wno-invalid-offsetof
  • -Wvolatile-register-var
  • -Wparentheses


読んでて __attribute__ は aligned 以外を知らない自分のダメっぷりに気づく。‥‥ざっとググってみたけど、あんまり必要なさそう‥‥かなぁ。

-Wcast-qual はポインタの型修飾子を変えるキャストをすると警告してくれるらしいんだけど、ポインタだけじゃなくて、参照もなんとかしてくれたらいいのに。コンパイラの仕組みはまったく知らんけど難しいのかな。もしくは要らない子なのかな。

void hoge(const A* a)
{
  ((A*)a)->a = 100;
}

↑は -Wcast-qual 使えば警告出るけど
↓は出ない。

void huga(const A& a)
{
  ((A&)a).a = 100;
}

さすがに、こんな酷いことする人、いないよねっ☆ ってことか? const_cast を使わない const 外しなんて死ねばいいのに。

で、本当に死んでもらうなら、-Wold-style-cast

世の中では、散々、C のキャストは使わずに、C++ のキャスト使おうねって言われてるのに、-Wold-style-cast を使おう、にはならないのは、さすがにまったく使わないのは厳しいからなんだろうか。いい機会だから使ってみよう。と思ったら、仕事上、使わないといけない C のヘッダで、キャストを含んだ #define があって涙目。数が少なかったので、キャストだけ自前で直してしばらく続ける。問題なのは、過去のソースとかライブラリとかなんだろうけど。どこで壁にぶつかるかしら。

-Werror って、世の中ではどのくらい使われてるものなんだろう。普段のビルドはともかく、-D NDEBUG したら assert のためだけに使ってる変数で大量に unused 出た! いつも、NDEBUG があるときの unused はあきらめてます!(どーん) ‥‥良い子は真似しないでね。うーん、これ地道な方法じゃなくて気持ちよく解決する方法ないんかな。

-Wundef。未定義のものは零になってると思って使ってしまってるな。これはいいや。スペルミスしなければ OKポッキー。

float-equal は、変更が無いかの確認のときに割と使っちゃってるからなー、直すべきかなー。

試すまでも無く -Wshadow なんて使ったら私のコンパイル結果は警告だらけです this 隠しまくってるから!

struct FVector2 {
  float x, y;
  FVector2(float x, float y) : x(x), y(y) {}
};

g++ -Wshadow -c -o sample.o sample.cpp
sample.cpp: In constructor `FVector2::FVector2(float, float)':
sample.cpp:3: warning: declaration of 'y' shadows a member of 'this'
sample.cpp:3: warning: declaration of 'x' shadows a member of 'this'

最適化オプション

うーん‥‥、最適化がかかるとマズイ場合ってのが、どんな時なのかがわかってないからだめだ。読んでる途中で、-O2 か -O3 だけでいいよという結論に達したのだった。べ、別にめんどくさくなったわけじゃ(ry

-I- 非推奨

-iquote 使いましょう。

デバッグ関連

華麗にスルー。

-g と -pg だけで今はあんまり困ってない。困ったら読む。

-m 系

疲れたのでいつか‥‥見ない

-f 系

疲れたのでいつか‥‥見ない




同じ警告を VC++ で出せるのか、出すにはどうすればいいのかを調べないといけなくなる罠。やっぱりデフォルトが一番ですよね☆(元も子もない)