

何の変哲もないコードなのですが、Galaxy S5およびAndroid 5.1.1の組合せの場合  
のみ、do/while文が不可解な動きをします。原因をご存知の方はいらっしゃらない  
でしょうか？

[code]

    int i = 0;
    int j = 0;
    
    do {
        Log.d(TAG, "[test do-while 1] i = " + i + ", j = " + j);
        i = 0;
        Log.d(TAG, "[test do-while 2] i = " + i + ", j = " + j);
        i++;
        Log.d(TAG, "[test do-while 3] i = " + i + ", j = " + j);
        i++;
        Log.d(TAG, "[test do-while 4] i = " + i + ", j = " + j);
        j++;
        Log.d(TAG, "[test do-while 5] i = " + i + ", j = " + j);
    } while (j < 5);
    
[/code]

Galaxy S5 (Android 5.1.1)で出力したログは以下の通りです。

[code]

    D/MainActivity( 9856): [test do-while 1] i = 2, j = 0
    D/MainActivity( 9856): [test do-while 2] i = 2, j = 0
    D/MainActivity( 9856): [test do-while 3] i = 2, j = 0
    D/MainActivity( 9856): [test do-while 4] i = 2, j = 0
    D/MainActivity( 9856): [test do-while 5] i = 2, j = 1
    D/MainActivity( 9856): [test do-while 1] i = 2, j = 1
    D/MainActivity( 9856): [test do-while 2] i = 2, j = 1
    D/MainActivity( 9856): [test do-while 3] i = 2, j = 1
    D/MainActivity( 9856): [test do-while 4] i = 2, j = 1
    D/MainActivity( 9856): [test do-while 5] i = 2, j = 2
    D/MainActivity( 9856): [test do-while 1] i = 2, j = 2
    D/MainActivity( 9856): [test do-while 2] i = 2, j = 2
    D/MainActivity( 9856): [test do-while 3] i = 2, j = 2
    D/MainActivity( 9856): [test do-while 4] i = 2, j = 2
    D/MainActivity( 9856): [test do-while 5] i = 2, j = 3
    D/MainActivity( 9856): [test do-while 1] i = 2, j = 3
    D/MainActivity( 9856): [test do-while 2] i = 2, j = 3
    D/MainActivity( 9856): [test do-while 3] i = 2, j = 3
    D/MainActivity( 9856): [test do-while 4] i = 2, j = 3
    D/MainActivity( 9856): [test do-while 5] i = 2, j = 4
    D/MainActivity( 9856): [test do-while 1] i = 2, j = 4
    D/MainActivity( 9856): [test do-while 2] i = 2, j = 4
    D/MainActivity( 9856): [test do-while 3] i = 2, j = 4
    D/MainActivity( 9856): [test do-while 4] i = 2, j = 4
    D/MainActivity( 9856): [test do-while 5] i = 2, j = 5
    
[/code]

それ以外の組合せで試すと以下の通り想定通りの動きをします。

[code]

    D/MainActivity( 9515): [test do-while 1] i = 0, j = 0
    D/MainActivity( 9515): [test do-while 2] i = 0, j = 0
    D/MainActivity( 9515): [test do-while 3] i = 1, j = 0
    D/MainActivity( 9515): [test do-while 4] i = 2, j = 0
    D/MainActivity( 9515): [test do-while 5] i = 2, j = 1
    D/MainActivity( 9515): [test do-while 1] i = 2, j = 1
    D/MainActivity( 9515): [test do-while 2] i = 0, j = 1
    D/MainActivity( 9515): [test do-while 3] i = 1, j = 1
    D/MainActivity( 9515): [test do-while 4] i = 2, j = 1
    D/MainActivity( 9515): [test do-while 5] i = 2, j = 2
    D/MainActivity( 9515): [test do-while 1] i = 2, j = 2
    D/MainActivity( 9515): [test do-while 2] i = 0, j = 2
    D/MainActivity( 9515): [test do-while 3] i = 1, j = 2
    D/MainActivity( 9515): [test do-while 4] i = 2, j = 2
    D/MainActivity( 9515): [test do-while 5] i = 2, j = 3
    D/MainActivity( 9515): [test do-while 1] i = 2, j = 3
    D/MainActivity( 9515): [test do-while 2] i = 0, j = 3
    D/MainActivity( 9515): [test do-while 3] i = 1, j = 3
    D/MainActivity( 9515): [test do-while 4] i = 2, j = 3
    D/MainActivity( 9515): [test do-while 5] i = 2, j = 4
    D/MainActivity( 9515): [test do-while 1] i = 2, j = 4
    D/MainActivity( 9515): [test do-while 2] i = 0, j = 4
    D/MainActivity( 9515): [test do-while 3] i = 1, j = 4
    D/MainActivity( 9515): [test do-while 4] i = 2, j = 4
    D/MainActivity( 9515): [test do-while 5] i = 2, j = 5
    
[/code]

その他確認した事実は以下の通りです。

・while文やfor文に書き換えると問題は発生しない。  
・logを疑って自作ログに置き換えても事象は変わらない。  
・Galaxy S4およびS6では発生しない、Anroid 5.0.2でも発生しない。


CC BY-SA 3.0
2015-07-23T00:42:47.767
12590
2015-07-27T03:02:36.873
10635
question
android java
Galaxy S5とAndroid 5.1.1でdo/whileが正しく機能しない


何らかの最適化が行われているという可能性はないでしょうか？

例えば、 _Log.d()_ はアプリのリリース時に、取り除かれたと仮定すると、

[code]

    int i = 0;
    int j = 0;
    
    do {
        i = 0;
        i++;
        i++;
        j++;
    } while (j < 5);
    
[/code]

実質的にこのような形であり、最適化によって、 _i = 0;_ から _i++;_ への 3 行が、 _i = 2_
とまとめられてしまうことが考えられます。

[code]

    int i = 0;
    int j = 0;
    
    do {
        i = 2;
        j++;
    } while (j < 5);
    
[/code]

その上で、改めて、 _Log.d()_ を再配置したような結果となっているように思われます。

もし、この推測（最適化の影響であるということ）が正しければ、最適化を妨げるような形にすれば、結果が違うはずです。

[code]

    int i = 0;
    int j = 0;
    int k = 0;
    
    do {
        Log.d(TAG, "[test do-while 1] i = " + i + ", j = " + j);
        i = 0;
        Log.d(TAG, "[test do-while 2] i = " + i + ", j = " + j);
        i++;
        k += i;
        Log.d(TAG, "[test do-while 3] i = " + i + ", j = " + j);
        i++;
        k += i;
        Log.d(TAG, "[test do-while 4] i = " + i + ", j = " + j);
        j++;
        Log.d(TAG, "[test do-while 5] i = " + i + ", j = " + j);
    } while (j < 5);
    
    Log.d(TAG, "k = " + k);
    
[/code]

たとえば、このようにすることによって、 _k_ の演算が間に割り込むことによって、 _i_ に関する 3 行を _i = 2_
とまとめて最適化するわけにはいかなくなるので、期待していた通りの結果になるのではないでしょうか？


CC BY-SA 3.0
2015-07-23T12:21:41.730
12623
2015-07-23T12:21:41.730
7290
12590
answer