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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

6回答

7116閲覧

コンパイルエラーではなく、無限ループの理由

k_mail

総合スコア90

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2016/03/23 06:24

Java SE7 Silver の資格を目指し勉強中です。
分からない点は
・ 6,7行目でコンパイルエラーではなく、無限ループになる理由

1 public class Main{
2 public static void main(String[] args){
3 int[] array = {1,2,3};
4 for(int num : array){
5 int i = 1;
6 while(i <= num);
7 System.out.println(i++);
8 }
9 }
10}

答えは「無限ループになり、何も表示されない」です。
これは6行目がwhile(1 <= 1);となるからでしょうか

また、そうした場合、7行目に到達不可能なコードがあるように思い、コンパイルエラーになるのではとも思います。(選択肢には「コンパイルエラーが発生する」というものもあります)
なぜ、コンパイルエラーではなく、無限ループが答えになるのでしょうか

返信は夜になると思いますが、よろしくお願いします。

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

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

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

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

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

guest

回答6

0

コンパイラの到達不能コード検出は通り一遍のものでして、
条件分岐(ifやwhileのことですね)の条件がどちらに転んだとしてもたどり着けない行があるときだけ検出してくれます。

もしもっと賢く、事実上到達できない行を検出するようにしようとしたらどうなるかというと、実際にコードを実行してみないといけなくなるため、このコードのように無限ループに陥るコードだとコンパイラがフリーズしてしまうことになります。だから、そんな“賢い”到達不能コード検出はされません。

投稿2016/03/23 06:29

yuba

総合スコア5568

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

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

k_mail

2016/03/23 19:13

返信が遅くなり申し訳ございません。 「 条件分岐(ifやwhileのことですね)の条件がどちらに転んだとしてもたどり着けない行があるときだけ検出」 大変わかりやすく、勉強になりました。 有難うございます。
guest

0

これは引っかけ問題ですね。

ご質問のコードをEclipseなどのIDEに転記し、フォーマットを整形すると以下のようになります。

java

1public class Main { 2 public static void main(String[] args) { 3 int[] array = { 1, 2, 3 }; 4 for (int num : array) { 5 int i = 1; 6 while (i <= num) 7 ; 8 System.out.println(i++); 9 } 10 } 11}

じつは、

java

1System.out.println(i++);

while句の外側に位置しており、while句の中でi++が実行されないため、正解は
「無限ループになり、何も表示されない」
となります。

---------以下、追記

失礼しました。

これは6行目がwhile(1 <= 1);となるからでしょうか

とおっしゃっているので、無限ループになることは認識されていたのですね。

なぜ、コンパイルエラーではなく、無限ループが答えになるのでしょうか

おそらく、【全ての】到達不可能コードをコンパイラに検出させることが難しいからではないでしょうか?
stackoverflowでも同様の話題があり、多分、そのような回答がなされていますw

http://stackoverflow.com/questions/3795585/why-does-java-have-an-unreachable-statement-compiler-error

ちなみに、以下のようにreturn句やthrow句のあとに実行行を書いた場合は、コンパイルエラーとなります。

java

1return; 2System.out.println("hoge");

これは、コンパイラから見ても到達不可能であることが明らかだからだと思われます。

投稿2016/03/23 06:38

編集2016/03/23 06:57
KiyoshiMotoki

総合スコア4791

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

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

k_mail

2016/03/23 19:12

返信が遅くなり申し訳ございません。 リンクも貼っていただき、勉強になります。 有難うございました。
guest

0

ベストアンサー

コンパイラの立場になって考えて見れば、

java

1public class Main { 2 public static void main(String[] args) { 3 while(true) ; // 継続条件が確定でtrueで、breakがないから… 4 System.out.println(); // どうやってもここ来れないじゃん -> エラー 5 } 6}

java

1public class Main { 2 public static void main(String[] args) { 3 boolean b = true; 4 while(b) ; //boolean型の変数だけど、変化の余地があるな… 5 System.out.println(); // 変更されたらここに来れるかもしれない 6 } 7} 8

java

1public class Main { 2 public static void main(String[] args) { 3 final boolean b = true; 4 while(b) ; // boolean型の変数だけどfinal?じゃあtrueから動きようないな 5 System.out.println(); // 絶対ここ来れないな -> エラー 6 } 7}

java

1String str = "1"; 2 3if (1 == 2) { // boolean型が返ってくるのはわかるけど、結果は今の時点じゃわからないな 4 str = "2"; // 結果次第ではここ通るかもな 5}

投稿2016/03/23 17:46

swordone

総合スコア20651

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

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

k_mail

2016/03/23 19:04

非常に分かりやすかったです。 有難うございます。
guest

0

「プログラムが停止するかどうかを判定する」問題は停止問題という名前がつくぐらい由緒正しい問題ですが、「どんなプログラムについても、停止するかしないか正しく判定できる」方法は、存在しないことが示されています。

完璧を実現することは不可能な以上、コンパイラとしても「できる範囲だけすればいい」というわけで、コンパイル時に定数となる条件だけ判定する、というのが通常です。

投稿2016/03/23 07:12

maisumakun

総合スコア145183

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

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

k_mail

2016/03/23 19:06

返信が遅くなり申し訳ございません。 ご回答有難うございました
guest

0

コンパイラはプログラムを実行しませんので、その時点の変数の値によって無限ループになる構文は、無限かどうか判断できません。
while(true);と書くと無限ループと判断してコンパイルエラーになります。

投稿2016/03/23 06:39

otn

総合スコア84533

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

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

KiyoshiMotoki

2016/03/23 07:20

以下の環境ではコンパイルエラーとならず、実行もできました。 マシン : MacBook Air 10.9.5 JDK :  1.6.0_65-b14-466.1  1.7.0_45  1.8.0_60 実行コード public class Main {  public static void main(String[] args) {   while (true);  } } コンパイラの実装によっても異なるのかもしれませんね。
heignamerican

2016/03/23 11:47

Java コンパイラが無限ループに対してエラーを吐くことは無い…と思います。 コンパイラがエラーと報告するのは、 while(true); のように明らかな無限ループの『後に』処理があるもの=到達不能コードで、無限ループそのものをエラー扱いはしないはずです。 otn さんが言及しているのは、元の質問コードの 6 行目を書き換えると~という意味なのでしょう。
otn

2016/03/23 12:41

> 以下の環境ではコンパイルエラーとならず、実行もできました。 到達不能文が何も書いて無いんですけど。それだとエラーになりようがない。無限ループ自体は正常です。
KiyoshiMotoki

2016/03/23 12:57

heignamerican 様、otn 様、ご指摘ありがとうございます。 うっかりしておりました。 おっしゃるとおり、以下のようにコードを修正すると、コンパイルエラーとなりました。 public class Main {  public static void main(String[] args) {   while(true) ;   System.out.println();  } } ちなみに、以下のようにwhile句の中を変数化するとコンパイルできますが、 public class Main {  public static void main(String[] args) {   boolean b = true;   while(b) ;   System.out.println();  } } 変数にfinal修飾子を付けると、再びコンパイルエラーとなりました。 public class Main {  public static void main(String[] args) {   final boolean b = true;   while(b) ;   System.out.println();  } } コンパイラの内部がうかがい知れるようで、興味深いですね。
k_mail

2016/03/23 19:10

返信が遅くなり申し訳ございません。 実際にコードも書いて調べていただきありがとうございます。 勉強になりました。
guest

0

Java

1String str = "1"; 2 3if (1 == 2) { 4 str = "2"; //実際は絶対入らないけどコンパイルは通る 5}

みたいなコードでもコンパイルエラーにはなりませんね。
「判定した結果、到達しない」みたいなコードはコンパイルエラーにならない気がします。

判定などの要素が全く無く、かつ絶対にその先には行かない、という場合にエラーになる気がします。

String str = "1"; return; str = "2"; //到達不可能 コンパイルエラー
String str = "1"; if (1 == 1) { return; } str = "2"; //これはエラーにならない

Java

1String str = "1"; 2int num = 0; 3 4if (num == 0) { 5 str = "a"; 6} else if (num != 0) { 7 str = "b"; 8} else { 9 str = "c"; //ここも絶対来ないけどエラーにならない 10}

投稿2016/03/23 07:03

sk_3122

総合スコア1126

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

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

k_mail

2016/03/23 19:08

返信が遅くなり申し訳ございません。 「判定した結果、到達しないみたいなコードはコンパイルエラーにならない」 勉強になりました。 ご回答有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問