質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

6482閲覧

オーバーフローの例外処理

tanukitii

総合スコア44

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2018/07/25 12:51

※古いですが,統合開発環境はvisual stdio 2010を使用しています。

言語はC++で,例外処理を学んでいました。

以下,私が書いたコードと質問内容を述べます。

#include "stdexcept"; using namespace std; int main() { int Max = 2147483647; int plus; try { plus = Max + 1; } catch(overflow_error e) { cerr << e.what() << endl; } //上記で例外を投げるはずなので以下は表示されないはずなのですが… cout << "合計値は" << plus << "です" << endl; return 0; }

質問内容
1.このコードを実行すると例外を投げてはくれず,「合計値は-2147483647です」と表示されます。int型の変数plusは演算時にintの範囲を超えた数値を扱うので,例外を投げるはずだと思っていたのですが,うまくいきません。

2.int型の最大数値を手打ちで入力しています。最大の整数を求めて,それを使用することはできないのでしょうか。C#ではint.MaxValueとかで求められますがC++でできるかがわかりませんでした。

3.C++には例外クラスがありますが,統合開発環境が古いので対応していないのでしょうか。

以上です。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

  1. int型の変数plusは演算時にintの範囲を超えた数値を扱うので,例外を投げるはずだ

残念ながら、C++で符号付き整数が溢れたときの処理は、「未定義の動作」(何が起きても問題ない)です。例外を投げてくれる処理系ももしかしたらあるかもしれませんが、全く一般的ではありません。

現実問題としては「黙って下位ビットだけ取り出す」というような動作になるコンパイラも多いですが、これも規格で保証されたものではありません(符号なし整数については、「下位ビットだけ取り出す」という動作が保証されています)。

  1. int型の最大数値を手打ちで入力しています。最大の整数を求めて,それを使用することはできないのでしょうか。C#ではint.MaxValueとかで求められますがC++でできるかがわかりませんでした。

<climits>INT_MAX、あるいは<limits>からstd::numeric_limits<int>::max()を使えます。

(3. は「そもそも例外が飛ばない」ので省略します)

投稿2018/07/25 12:56

編集2018/07/25 12:59
maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanukitii

2018/07/25 13:11 編集

ご回答誠にありがとうございます。 C++ではできないのですか… 追加で質問をしたいのですが, 1.「未定義の動作」ということは,そもそもオーバーフローのような状況は想定されていないということでしょうか。 2.例外クラスのoverflow_errorはなんのためにあるのでしょうか?? よろしくお願いします。
maisumakun

2018/07/25 13:22 編集

1. C++では、符号付き整数の入れ方として「2の補数」以外に「1の補数」「符号+絶対値」のような表現も認められています。そして、一部の値(2の補数で、最上位だけ立った状態や、それ以外の表現での「-0」)を、正常な整数としてではなく、演算不能な「トラップ表現」として扱う機械も存在します。 C++は極端にオーバーヘッドを嫌う言語ですので、このような場合に特定の動作を強いて余計なオーバーヘッドを作り込むよりは、処理系任せにして「オーバーフローした場合は保証しない」とする方針をとっています(トラップ表現を踏んだ場合のこともあるので、処理継続すら保証されない「未定義動作」となっています)。 http://www.kijineko.co.jp/tech/creintro/integer-representation.html 2. overflow_errorを標準関数で投げるのは std::bitset::to_ulong と std::bitset::to_ullongだけで、基本的には数学演算をするサードパーティのライブラリ用、とのことです。 https://ja.cppreference.com/w/cpp/error/overflow_error
tanukitii

2018/07/26 22:39

そうだったのですか… 勉強になりました。後ほど,上記のサイトも見てみようと思います。 ご回答ありがとうございました。
guest

0

以下を参考にしてみてください。

C++ における整数型の怪と "移植性のある" オーバーフローチェッカー (第1回 : 整数型の怪と対策の不足)

第5回まで投稿があります。(なおこの投稿に対する質問はQiitaで投稿者にお願いしますね)

投稿2018/07/26 08:45

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanukitii

2018/07/26 22:37

上記のサイトを参考にします。 ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問