gccには-Weverythingがない(clangにはあるのに)

`gcc -Wall`がぜんぜんallじゃないのは既知として。でも知ってるよそれって`-Wextra`でしょ、って思うと、実はそれでもまだ有効にならない警告というものが存在する。しかもかなり山ほど存在する。

これは主として歴史的経緯によるものらしい。たとえば`-Weffc++`というのはそういうオプションの一つだけれど、infoを読むことにより

> Warn about violations of the following style guidelines from Scott Meyers’ Effective C++ series of books

などと書かれていて、さすがにこれは…という。つまりgccにはこのような過去の残念な警告というものがチリツモでたくさんあり、全部を有効にするというのはあまり現実的ではないわけだ。

とはいえ。ゴミの山の中だったとしても埋もれている有意義な警告というものもある可能性は否定できない。一体どのようなオプションが存在し得るのだろうか?

## 一覧を得る

じつはオプションの一覧をリストしてくれる便利な機能がgccには含まれていて、`gcc --help=c` などとすることによりCで有効なオプションの一覧を取得することができる。中には "This option lacks documentation." などと書かれているものもあり、なかなか怪しい(しかも`gcc -E`とか…ドキュメントないのかよ)。が、逆に言うと、怪しい奴まで含めて網羅的に出てくる。

これと`-Q`を組み合わせることによりあるオプションが有効かどうかということを知ることができる。

```zsh
zsh % g++-trunk -Q -Wall -Wextra --help=c | fgrep disabled | head
  -E                                    [disabled]
  -Wabi                                 [disabled]
  -Walloc-zero                          [disabled]
  -Walloca                              [disabled]
  -Wbad-function-cast                   [disabled]
  -Wc++-compat                          [disabled]
  -Wcast-qual                           [disabled]
  -Wconversion                          [disabled]
  -Wdate-time                           [disabled]
  -Wdouble-promotion                    [disabled]
```

もうすこしワンライナーを書いて、markdownを吐き出すようにしてみる:

```zsh
zsh % ruby <<'RUBY' | pbcopy
descriptions = `g++-trunk --help=c` \
                 . each_line \
                 . slice_before(/^  -/) \
                 . map(&:join)
                 . map {|i| i.strip.split(/(?=\s+\w)/, 2) }\
                 . map {|i| i.map {|j| j.strip.gsub(/\s+/, ' ' ) } }
disabled     = `g++-trunk -std=c89 -pedantic -Wall -Wextra -Q --help=c` \
                 . each_line \
                 . grep(/disabled/) \
                 . map {|i| i[/\S+/] } \
                 . inject({}) {|r, i| r[i] = true; r }

puts <<md
| option | description |
| ------ | ----------- |
md
descriptions.each do |(opt, desc)|
  next unless disabled[opt]
  printf("| %s | %s |\n", opt, desc)
end
RUBY
```

結果はこうだ:

## 一覧

| option | description |
| ------ | ----------- |
| `-E` | This option lacks documentation. |
| `-Wabi` | Warn about things that will change when compiling with an ABI-compliant compiler. |
| `-Walloca` | Warn on any use of alloca. |
| `-Wbad-function-cast` | Warn about casting functions to incompatible types. |
| `-Wc++-compat` | Warn about C constructs that are not in the common subset of C and C++. |
| `-Wcast-qual` | Warn about casts which discard qualifiers. |
| `-Wconversion` | Warn for implicit type conversions that may change a value. |
| `-Wdate-time` | Warn about `__TIME__`, `__DATE__` and `__TIMESTAMP__` usage. |
| `-Wdouble-promotion` | Warn about implicit conversions from `float` to `double`. |
| `-Wduplicated-branches` | Warn about duplicated branches in if-else statements. |
| `-Wduplicated-cond` | Warn about duplicated conditions in an if-else-if chain. |
| `-Werror` | Treat all warnings as errors. |
| `-Wfloat-conversion` | Warn for implicit type conversions that cause loss of floating point precision. |
| `-Wfloat-equal` | Warn if testing floating point numbers for equality. |
| `-Wformat-nonliteral` | Warn about format strings that are not literals. |
| `-Wformat-security` | Warn about possible security problems with format functions. |
| `-Wformat-signedness` | Warn about sign differences with format functions. |
| `-Wformat-y2k` | Warn about strftime formats yielding 2-digit years. |
| `-Winit-self` | Warn about variables which are initialized to themselves. |
| `-Winvalid-pch` | Warn about PCH files that are found but not used. |
| `-Wjump-misses-init` | Warn when a jump misses a variable initialization. |
| `-Wlogical-op` | Warn when a logical operator is suspiciously always evaluating to true or false. |
| `-Wmissing-declarations` | Warn about global functions without previous declarations. |
| `-Wmissing-include-dirs` | Warn about user-specified include directories that do not exist. |
| `-Wmissing-prototypes` | Warn about global functions without prototypes. |
| `-Wmultichar` | Warn about use of multi-character character constants. |
| `-Wnested-externs` | Warn about `extern` declarations not at file scope. |
| `-Wold-style-definition` | Warn if an old-style parameter definition is used. |
| `-Wredundant-decls` | Warn about multiple declarations of the same object. |
| `-Wrestrict` | Warn when an argument passed to a restrict- qualified parameter aliases with another argument. |
| `-Wsign-conversion` | Warn for implicit type conversions between signed and unsigned integers. |
| `-Wstrict-prototypes` | Warn about unprototyped function declarations. |
| `-Wsuggest-attribute=format` | Warn about functions which might be candidates for format attributes. |
| `-Wswitch-default` | Warn about enumerated switches missing a `default:` statement. |
| `-Wswitch-enum` | Warn about all enumerated switches missing a specific case. |
| `-Wsystem-headers` | Do not suppress warnings from system headers. |
| `-Wtraditional` | Warn about features not present in traditional C. |
| `-Wtraditional-conversion` | Warn of prototypes causing type conversions different from what would happen in the absence of prototype. |
| `-Wundef` | Warn if an undefined macro is used in an #if directive. |
| `-Wunsuffixed-float-constants` | Warn about unsuffixed float constants. |
| `-Wunused-macros` | Warn about macros defined in the main file that are not used. |
| `-Wwrite-strings` | In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard. |
| `-fallow-parameterless-variadic-functions` | Allow variadic functions without named parameter. |
| `-fasm` | Recognize the `asm` keyword. |
| `-fbuilding-libgcc` | This option lacks documentation. |
| `-fcheck-pointer-bounds` | Add Pointer Bounds Checker instrumentation. fchkp-* flags are used to control instrumentation. Currently available for C, C++ and ObjC. |
| `-fchkp-first-field-has-own-bounds` | Forces Pointer Bounds Checker to use narrowed bounds for address of the first field in the structure. By default pointer to the first field has the same bounds as pointer to the whole structure. |
| `-fchkp-flexible-struct-trailing-arrays` | Forces Pointer Bounds Checker to treat all trailing arrays in structures as possibly flexible. By default only arrays fields with zero length or that are marked with attribute bnd_variable_size are treated as flexible. |
| `-fchkp-instrument-marked-only` | Instrument only functions marked with bnd_instrument attribute. |
| `-fchkp-narrow-to-innermost-array` | Forces Pointer Bounds Checker to use bounds of the innermost arrays in case of nested static arrays access. By default outermost array is used. |
| `-fchkp-treat-zero-dynamic-size-as-infinite` | With this option zero size obtained dynamically for objects with incomplete type will be treated as infinite. |
| `-fchkp-use-fast-string-functions` | Allow to use *_nobnd versions of string functions by Pointer Bounds Checker. |
| `-fchkp-use-nochk-string-functions` | Allow to use *_nochk versions of string functions by Pointer Bounds Checker. |
| `-fchkp-zero-input-bounds-for-main` | Use zero bounds for all incoming arguments in 'main' function. It helps when instrumented binaries are used with legacy libs. |
| `-fcilkplus` | Undocumented Deprecated in GCC 8. This switch has no effect. |
| `-fdump-ada-spec` | Write all declarations as Ada code transitively. |
| `-fdump-ada-spec-slim` | Write all declarations as Ada code for the given file only. |
| `-fgimple` | Enable parsing GIMPLE. |
| `-flax-vector-conversions` | Allow implicit conversions between vectors with differing numbers of subparts and/or differing element types. |
| `-fms-extensions` | Don't warn about uses of Microsoft extensions. |
| `-fopenacc` | Enable OpenACC. |
| `-fopenmp` | Enable OpenMP (implies -frecursive in Fortran). |
| `-fopenmp-simd` | Enable OpenMP's SIMD directives. |
| `-fplan9-extensions` | Enable Plan 9 language extensions. |
| `-fshort-wchar` | Force the underlying type for `wchar_t` to be `unsigned short`. |
| `-funsigned-bitfields` | When `signed` or `unsigned` is not given make the bitfield unsigned. |
| `-funsigned-char` | Make `char` unsigned by default. |
| `-undef` | Do not predefine system-specific and GCC-specific macros. |
| `-v` | Enable verbose output. |
| `-w` | Suppress warnings. |

上記の通りでこの全部を有効にするのはあまり現実的ではないだろう。しかし中には、指定しておくと便利なものはあるかもしれない。