C++と++APARとインクリメント演算子

AIXとかのIBMの世界には「++APAR」(ぷらぷらえーぱー)ってものがあっていわゆる修正パッチのことを指します。
APARは「Authorized Problem Analysis Reports」の略でバグ番号の意味。
APARとかifixってなに? - 自分の仕事を憎むには人生は余りにも短い

んでバグ番号が修正されるから修正パッチは「++APAR」って訳です。決して「APAR++」ではだめだよねって話を前したら思ったより通じなかった。

まあ確かにあんまインクリメント演算子の前後なんて意識しないよね。Forの中でカウンタ回すときぐらいしか使わないし。。。
ちなみに一応書いておくと

    int a = 10;
    System.out.println(++a);
    System.out.println(a++);
    System.out.println(a);

のような感じで実行すると

11
11
12

となります。

  • 「++a」は代入される前に加算されて
  • 「a++」は代入されてから加算される

そこから「C++」を考えると使ってる(コーディングしてる)ときはCなんだけどあとで気づいたらいつの間にか改善されてるって主張なのかな?
名前もちゃんと考えると面白い。

a = a++

ところで

    a = 20;
    a = a++;

とか書くといったい何をしているのかわからなくなって来るので書いちゃだめです。というかやってはだめです。
ひとつの式で同一の変数が2回以上変更される場合で、その順序が明確に定義されていない場合その結果は「未定義」として扱われます。つまりどう動くか言語使用として決めてませんよってこと。VMや動作環境によって挙動が変わる可能性があるということですね
たとえば上記を実行すると

  • JavaC#の場合「20」
  • Cの場合「21」

となります。
これは上記のようにインクリメント演算子の中の「設定」の部分をいつ実行するか言語仕様として決まっていないからです。



Javaの場合言語仕様として計算式の中ではインクリメントはまず最初に評価されるのですが「設定」は未定。
計算式の中で優先的に処理される例として、たとえば以下の場合bもcも結果は10になる。

a = 1;
b = ++a * 5;
c = a++ * 5;

でも上の「a = a++」だと設定のほうが先に評価されている。

C#は明示的に未定義とうたってる。

優先順位が同じ演算子が式に 2 つ含まれている場合、それらの演算子は、結合規則に基づいて評価されます。結合規則が左から右の演算子は、左から右に評価されます。たとえば、x * y / z は (x * y) / z と評価されます。結合規則が右から左の演算子は、右から左に評価されます。代入演算子三項演算子 (?:) は、結合規則が右から左です。他の二項演算子はすべて結合規則が左から右です。ただし、C# の標準では、式の中でインクリメント命令の "設定" 部分をいつ実行するかを指定していません。

http://msdn.microsoft.com/ja-jp/library/ms173145%28VS.80%29.aspx

インクリメントとか簡単なところにも罠があるので気をつけましょう。