2011-05-12 1 views
3

変数xが以下のコードスニペットで定数として宣言されている場合、clang 2.9とg ++ 4.1.2の両方で警告が生成されます。しかし、のconstが削除された場合、スニペットに記載されているように、私が知っている以下のパラメータで実行しても警告は生成されません。 "-Wall -Wextra -pedantic -ansi"const以外の変数をより小さな型の変数に代入して切り捨てるときに、g ++やclangが警告を出さないのはなぜですか?

xはvolatileではなく、型変換の前に変更することはできないため、コンパイラは同じ警告を推測して報告しません。

#include <iostream> 

int main(int argc, char **argv) 
{ 
    unsigned int x = 1000; 
    const unsigned char c = x; 
    const unsigned int x_ = c; 
    std::cout << "x=" << x << " x_=" << x_ << std::endl; 
    return 0; 
} 

とすると、符号なし整数x = 1000; g ++は、メッセージ「警告:暗黙的に符号なしタイプに切り捨てられました」とメッセージ「」を提供します。警告:「const unsigned int」から「const unsigned char」への暗黙的変換により、値が1000から232に変更されます[-Wconstant-conversion] "。

手動でコードを検査したり、正しく設計された単体テストに頼ったりしなければ、このケースを自動的に検出する方法はありますか?

答えて

4

を警告を発するフラグ-Wconversionを追加し、あなたが希望警告が表示されますすることができます前に、

はgccのインラインのような定数です。それは多くのコードがこれらのタイプのものを無視するだけなので、-Wallの一部ではありません。私はそれがそうでなければ欠陥をデバッグするのが難しいと感じるので、いつもそれをつけた。

+0

優秀、ありがとう!どうしてそれはWextraには含まれていないのですか?私はWextraが壁に収まらないものすべてを捕まえたと思った。 –

+0

私は分かりません。それは-Wextraの一部でなければなりません(私は実際に-Wallの一部でなければならないと思います)。 –

+0

@David:残念なことに '-Wextra'はキャッチオールではありません。アフガニスタンには、gccやclangには、すべてを活性化させる旗がありません。 –

2

constの場合、コンパイラはその値を参照して切り捨てについて警告することができます。それがconstでない場合、初期化にもかかわらず、できません。これは:-03 -fdumpツリー-VRPで

const unsigned char c = 1000; 
+1

控除を行うべき非const変数の値渡しの伝播パスがあります。 – vines

+2

確かに、GCCは、決して変更されないような非const整数変数のために放出されたコードで即時値を使用するのを見ました。 GCCは値があまりにも悲観的に見えるとは言えません。おそらく、この特定の警告段階では値を見ることはできません。 –

1

私が実行したGCC、と私はダンプに見るものは次のとおりです:

const unsigned int x = 1000; 
const unsigned char c = x; 

に相当します

std::__ostream_insert<char, std::char_traits<char> > (&cout, &"x="[0], 2); 
D.20752_20 = std::basic_ostream<char>::_M_insert<long unsigned int> (&cout, 1000); 
std::__ostream_insert<char, std::char_traits<char> > (D.20752_20, &" x_="[0], 4); 
D.20715_22 = std::basic_ostream<char>::_M_insert<long unsigned int> (D.20752_20, 232); 

つまり、cout文の定数1000と232をインライン化するだけです!

-0を指定して実行すると、-ftree-vrpおよび-ftree-ccpスイッチに関係なく、何もダンプしません。それは、... GCCの場合

関連する問題