「2016年、C言語はどう書くべきか」をちょっと分析してみる (warning編)

# Overview

原典は、https://matt.sh/howto-c (日本語訳を作ってくださっている方のページは http://postd.cc/how-to-c-in-2016-1/ )です。

ここでのいくつかについて、分析してみます。まずは、warning編から。

# 事前準備 section

## warning : -pedantic

http://clang.llvm.org/docs/UsersManual.html によると、

```
-pedantic
 Warn on language extensions.
```

とあります。Googleってみると、

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0742bj/chr1398848167694_00008.html

には、出力例があり、

```
$ armclang --target=aarch64-arm-none-eabi -c -pedantic --std=c90 test.c
  test.c:3:5: warning: anonymous structs are a C11 extension [-Wc11-extensions]

$ armclang --target=aarch64-arm-none-eabi -c -pedantic -xc++  test.c
  test.c:3:5: warning: anonymous structs are a GNU extension [-Wgnu-anonymous-struct]
```

こんなものを出力するとあります。

例えば、--std=cxxのように指定したcxxの言語たものを超えた言語拡張を使用したコードが合った場合に、warningを出してくれるということのようです。

## warning : -Wshadow

★追記、訂正★

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

```
-Wshadow
Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member (in C++), or instance variable (in Objective-C) or whenever a built-in function is shadowed. Note that in C++, the compiler warns if a local variable shadows an explicit typedef, but not if it shadows a struct/class/enum. 
```

local変数または型宣言が、他の変数、パラメータ、型、classメンバーや、インスタンス変数、built-inの関数をshadowするときに、warningします。なお、C++においては、local変数が明示的なtypedefをshadowするときにcompilerがwarningしますが、それは。structやclassやenumをshadowするときにはwarningしませんので、注意が必要です。

なお、未初期化をwarningしたい場合には、-Wmaybe-uninitializedのようなものもあるようです。

## warning : -Wstrict-overflow

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
によると、

```
-Wstrict-overflow
-Wstrict-overflow=n
This option is only active when -fstrict-overflow is active. It warns about cases where the compiler optimizes based on the assumption that signed overflow does not occur. Note that it does not warn about all cases where the code might overflow: it only warns about cases where the compiler implements some optimization. Thus this warning depends on the optimization level.
```

このoptionは、-fstrict-overflowが有効なときのみ有効です。 compilerが、signed overflowが発生しないと仮定して最適化を行った時に、warningをだします。
なお、すべてのoverflowするかもしれないケースについてwarningしないことに注意してください。つまり、compilerがいくつか最適化を行うケースについてのみwarningを出します。そして、このwarinigは、最適化レベルに依存します。

```
An optimization that assumes that signed overflow does not occur is perfectly safe if the values of the variables involved are such that overflow never does, in fact, occur. Therefore this warning can easily give a false positive: a warning about code that is not actually a problem. To help focus on important issues, several warning levels are defined. No warnings are issued for the use of undefined signed overflow when estimating how many iterations a loop requires, in particular when determining whether a loop will be executed at all.
```

もし、値の範囲が、overflowしないものが関与している場合は、signed overflowが発生しないと仮定されるoptimizationは、完全に安全です。ですので、このwarningは、容易にfalse positiveになり得ます。ですのでコードが実際に問題にならなくても、warningします。重要な問題にfocusするために、いくつかのwarning levelが定義されています。いくつのloopがiterateされるのかを仮定して、未定義のsigned overflowが使われている場合は、warningしません。特に、loopが実行時に完全にdeterministicな時には。


```
-Wstrict-overflow=1
Warn about cases that are both questionable and easy to avoid. For example, with -fstrict-overflow, the compiler simplifies x + 1 > x to 1. This level of -Wstrict-overflow is enabled by -Wall; higher levels are not, and must be explicitly requested. 
-Wstrict-overflow=2
Also warn about other cases where a comparison is simplified to a constant. For example: abs (x) >= 0. This can only be simplified when -fstrict-overflow is in effect, because abs (INT_MIN) overflows to INT_MIN, which is less than zero. -Wstrict-overflow (with no level) is the same as -Wstrict-overflow=2. 
-Wstrict-overflow=3
Also warn about other cases where a comparison is simplified. For example: x + 1 > 1 is simplified to x > 0. 
-Wstrict-overflow=4
Also warn about other simplifications not covered by the above cases. For example: (x * 10) / 5 is simplified to x * 2.
-Wstrict-overflow=5
Also warn about cases where the compiler reduces the magnitude of a constant involved in a comparison. For example: x + 2 > y is simplified to x + 1 >= y. This is reported only at the highest warning level because this simplification applies to many comparisons, so this warning level gives a very large number of false positives.
```

http://blog.kmckk.com/archives/4085604.html
にも参考になる記事があります。


## warning : -fno-strict-aliasing

* http://up-cat.net/gcc+option.html
* https://www.jpcert.or.jp/sc-rules/c-exp39-c.html
* http://d.hatena.ne.jp/yohhoy/20120220/p1

に参考になる記事があります。

```
Either specify -fno-strict-aliasing or be sure to only access objects as the type they have at creation. Since so much existing C code aliases across types, using -fno-strict-aliasing is a much safer bet if you don't control the entire underlying source tree.
```

-fno-strict-aliasingを指定するか、生成された時のtypeのobjectにアクセスするだけにするかをsureにしましょう。 というのは、既存のC codeは、typeを超えてaliasしているコードが多く存在するためです。ですので、あなたがすべてのソースツリーを制御できると言えないかぎり、-fno-strict-aliasingを使うのは、より安全な方にbetしていることになります。

## warning : -Wno-missing-field-initializers

(「-Wextra」は「-Wmissing-field-initializers」を含むため)

```
as of now, Clang reports some valid syntax as a warning, so you should add -Wno-missing-field-initializers
```

問題がないコードに、warningをレポートしてしまうので、-Wno-missing-field-initializersを追加すべきです。

とのことです。

http://d.hatena.ne.jp/shouh/20140510/1399680764
に参考になる記事があります。

[つづく](http://qiita.com/hidenorly/items/5831e8fa87f4a7adc2c9)