ここから本文です

VC 2010 なんですが、main に int i ; printf ( " %d\n %d\n", i = 1, i = 0 )...

アバター

ID非公開さん

2019/9/1705:47:56

VC 2010 なんですが、main に

int i ;
printf ( " %d\n %d\n", i = 1, i = 0 );
と書いて実行すると、
1
1

と表示されます。

int i , j ;
printf ( " %d\n %d\n", i = 1, j = 0 );
と書いて実行すると、
1
0
と表示されます。

同じ現象、起こりませんか?
他のバージョンも含めて。

補足質問に対して妥当なご回答に投票お願いします。

閲覧数:
62
回答数:
3
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

エヌさん

2019/9/1713:27:48

どんな現象が起きても不思議ではないです。いわゆる「鼻から悪魔」

  • アバター

    質問者

    ID非公開さん

    2019/9/1723:54:08

    ご回答、ありがとうございます。

    同じ結果を確認できましたか?

    上記の結果、論理的に、如何ですか?

  • その他の返信(4件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

プロフィール画像

カテゴリマスター

n2q********さん

2019/9/1709:42:24

まず、sequence point という用語で検索していただくと資料が見つかると思いますが、これが絡んでいます。

《資料の例》
https://en.wikipedia.org/wiki/Sequence_point


引数の評価順序は決まっていません。そして、その sequence point の中に i = 1, i = 0 という副作用の部分(i の値を変化させるというところ)が二つ入っていますので、こうなるとその効果としては未定義となってくるというわけです。




【同じ現象、起こりませんか?】

起こりますね、確かに。

~コード生成状況~

00CA13ED mov dword ptr [i],0
00CA13F4 mov dword ptr [i],1
00CA13FB mov esi,esp
00CA13FD mov eax,dword ptr [i]
00CA1400 push eax
00CA1401 mov ecx,dword ptr [i]
00CA1404 push ecx
00CA1405 push offset string " %d\n %d\n" (0CA573Ch)
00CA140A call dword ptr [__imp__printf (0CA82E0h)]
00CA1410 add esp,0Ch


《参考》

冒頭で i に 0 を代入し、そしてすぐに 1 を代入(上書き)しています。引数を push する前に、まずは代入の方を先に済ませる形ですね。

なお、

00CA13FB mov esi,esp

これは余計であり、何かの間違いの模様。あるいは何らかの秘密がある(あった)のかもしれません。



【他のバージョンも含めて】

Visual C++ 6.0の場合は 1 0 となりました。

~コード生成状況~

00401028 mov dword ptr [ebp-4],0
0040102F mov eax,dword ptr [ebp-4]
00401032 push eax
00401033 mov dword ptr [ebp-4],1
0040103A mov ecx,dword ptr [ebp-4]
0040103D push ecx
0040103E push offset string " %d\n %d\n" (0042201c)
00401043 call printf (00401070)
00401048 add esp,0Ch

i = 0 の代入を行い、それを push、i = 1 の代入を行い、それを push 、こういう流れです。



Visual C++ .NET 2003 の場合は 1 1 となりました。

~コード生成状況~

00411A5D mov dword ptr [i],0
00411A64 mov dword ptr [i],1
00411A6B mov eax,dword ptr [i]
00411A6E push eax
00411A6F mov ecx,dword ptr [i]
00411A72 push ecx
00411A73 push offset string " %d\n %d\n" (42401Ch)
00411A78 call @ILT+1170(_printf) (411497h)
00411A7D add esp,0Ch

基本的に Visual C++ 2010 と同じです。余計なコードは含まれていませんが。


Visual C++ 2019 の場合も 1 1 となりました。

~コード生成状況~

013124B7 mov dword ptr [i],0
013124BE mov dword ptr [i],1
013124C5 mov eax,dword ptr [i]
013124C8 push eax
013124C9 mov ecx,dword ptr [i]
013124CC push ecx
013124CD push offset string " %d\n %d\n" (013ADE50h)
013124D2 call _printf (0130C3E8h)
013124D7 add esp,0Ch

全く同じコードです。



《参考》

以上は全てデバッグ版になります。リリース版では、

Visual C++ 6.0 の場合

00401006 push 1
00401008 push 1
0040100A push 407030h
0040100F call 00401020
00401014 add esp,0Ch


Visual C++ 2019 の場合

01061046 push 1
01061048 push 1
0106104A push offset string " %d\n %d\n" (010774D8h)
0106104F call printf (01061010h)
01061054 add esp,0Ch


各バージョンとも同じ結果(出力は 1 1)になりました。

変数 i が不要であることを見破った形です。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

has********さん

2019/9/1707:52:40

どの辺りが疑問ですか?
特に変だとは思えませんが…。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる