VB : UInteger型の変数にULong型の値を代入するとどうなるか

先日、Office2007から2013への移行作業を行いまして。
その作業の一環として、VBで作ったアドインの移行も行ったわけです。

その際に、どうせだからと、開発環境もVS2008から2013に移行したんですね。

こうしたら、今まで通っていた計算式が通らない。具体的には、
Dim aaa As UInteger = bbb And &HFFFFFFFF
ここでOverflow Exceptionが発生するんです。
ちなみに、bbbはULong型の変数で、&H100000000以上の値が入っていると思ってください。

私は今回、人様がこしらえたアドインを修正しただけのかかわりだったので1行1行のコードまで細かく見ていなかったんですが、エラーが出て改めて見ると何やってんだこのコード、となったわけです。

たとえばbbbに&H1234567000000080という値が入っていたとして。
これと&HFFFFFFFFのAndを取るということは、下4バイト分を切り出したいということなんですけど。
どういうわけか「&H1234567000000080 And &HFFFFFFFF」の結果が「&H1234567000000080」になります。
VB2008でも2013でもなります。

私がAnd演算の意味を勘違いしているのかボケてきているのかもう歳なのかとも思ったんですが、「&H1234567000000080 And &HFFFFFFFFF」でも「&H1234567000000080 And &HFFFFFFF」でも結果は「&H80」になりますので、ビットごとの論理積で間違っちゃないと思うんです。

ということで5バイト以上の値に&HFFFFFFFFのAndを取ると、なぜか加工されない元の値が返されるという不思議。

で、さらに、aaaにbbb And &HFFFFFFFFの結果を代入すると、なぜかVB2008ではエラーになりません。5バイト以上の値を代入すると、下4バイト分だけが格納され、上の例で言えば「演算結果は&H1234567800000080なのに代入結果は&H80になる」という驚きのリアクションに。

これがVB2013で実行されると、代入時点でオーバーフローが発生します。むしろ当たり前。

ということで、今回のエラー原因は

  • VB2013でFixされたバグに依存したコードだったため
  • &HFFFFFFFFでAnd取った時の演算結果はやっぱりおかしいよね?

という結論に。

原因がわかってしまえば対処は簡単で、
Dim aaa As UInteger = bbb Mod &H100000000
としてやればいいだけなんですけど。

なんですけど。なんかこう、なんかこう…今いち納得がいかないのです。

0 件のコメント :

コメントを投稿