私はずっと前に行ったコードを持っていました(私はVisual Studio 2003を使っていました)。今私はgccを使用していますが、いくつかの値がオーバーフローしています。私は何が起こっているかを見て、それは驚きです。一時的な値を特定のデータ型に格納する際の算術演算の標準規則は何ですか?
ワークス(出力= 85):
int b = 35000000;
unsigned long a = 30000000;
unsigned long n = (100 * a)/b;
がいない作品(オーバーフロー):
int b = 35000000;
int a = 30000000;
unsigned long n = (100 * a)/b;
がいない作品(
は、私は何が起こっているかお見せしましょうオーバーフロー):int b = 35000000;
unsigned long n = (100 * 30000000)/b;
このshouすべて正しいと思います。今、何がバグですか?
unsigned long b= 35000000;
unsigned long n = (100 * 30000000)/b;
使いました!今それはしません。
実際にはまだMicrosoftのコンパイラで動作しますが、clangやgccでは動作しません。先に行くと、あなたがしたい場合は、別のコンパイラでコンパイル:http://rextester.com/BZU89042
Output = 85
- マイクロソフト(R)C/C++最適化コンパイラバージョン19.00.23506のx86Output = 527049830640
のために - G ++ 5.4.0Output = 527049830640
- clang 3.8.0
これに関する標準的なC++ルールは何ですか?
これは[整数リテラル](http://ja.cppreference.com/w/cpp/language/integer_literal)に関連していますか?標準によると、コンパイラは 'int'、' long int'、 'long long int'のいずれかを選択することができます(値が適合する場合) - GCCとclangは' int'を選択したようですVCは 'long long int'を選択しますか? – UnholySheep
コンパイラは 'int'から' long'に(C++ 11以降) 'long long'にリテラル値が収まらない場合は、型のサイズを拡張する必要があります。詳細については、[参考文献](http://en.cppreference.com/w/cpp/language/integer_literal)を参照してください)。しかし、 '100'と' 30000000'の両方は 'int'に入り、乗算を行いますオーバーフロー。しかし、コンパイラがいつどこでどこをフォールディングするかによって、VC++の振る舞いを説明するフォールディングの後に型拡張(intからlong longまで)*を行う可能性があります。 –
私の前のコメントはその動作を説明していますが、仕様書の内容についての質問には答えません。このことについて何も読んでいないと、定数フォールディングのような最適化が実装の詳細なので、実際に何も言わないということを推測します。したがって、その動作は*未定*です。それで、GCCとClangは、仕様の意図と手紙に従うことに近づくと思います。 –