UWP アプリケーション上で static UInt64 型の値がマイナスの値として扱われる場合があります。

 

こんにちは、Platform SDK (Windows SDK) サポートチームです。

今回は UWP アプリケーションの開発にあたり確認された問題についてご案内したいと思います。

 

現象

UWP アプリケーション上で static UInt64 型の値がマイナスの値として扱われる場合があります。この現象が発生する条件は以下の通りになります。

 

・ static UInt64 型の変数がグローバル変数として宣言されている

・ 数値が 32 ビットの値で、かつ最上位ビットが立っている

・ .NET Native としてビルドされている

 

再現コード例

public sealed partial class MainPage : Page

{

    static UInt64 memSize = 0x80000000;

    public MainPage()

    {

        this.InitializeComponent();

        textBlock.Text = memSize.ToString("X");

    }

}

 

期待される結果:80000000

実際の結果:FFFFFFFF80000000

 

原因

本現象は .NET Native ランタイム上でアプリケーション起動時に static UInt64 型の変数として宣言された 32 ビットの値を符号なし変数であるにも関わらず誤ってマイナスの値と解釈し、FFFFFFFF を追加する処理が行われています。弊社ではこの動作は .NET Native の不具合であることを確認しており、将来的な修正を予定しています。

 

回避策

この問題は以下の何れかの方法から回避いただくことができます。

1) .NET Native ビルドではなく、CLR ランタイムを利用するようにビルド。

Visual Studio 2015 または Visual Studio 2017 上で UWP アプリケーションをリリースビルドした場合、以下のように既定で .NET Native でコンパイルされるオプションが有効になります。このチェックを外してビルドを行うことで、リリースビルドであっても、CLR ランタイムを利用するように変更できます。

なお、.NET Native ビルドは予めマシンコードに変換されているため、パフォーマンスアップが見込めます。NET Native コンパイル オプションを外した場合、通常の .NET Framework アプリケーション同様ビルド時に中間コード (IL) が生成され、実行時に JIT コンパイラによりネイティブコードにコンパイルされますので、パフォーマンス面では影響を受けます。

 

clip_image001

 

2) 32ビットの値でかつ最上位が立っている値は FFFFFFFF を削除する処理を追加する。

この現象は 0x80000000 から 0xFFFFFFFF の間の値が static UInt64 型で宣言された場合発生します。この範囲の値を ToString メソッドを利用して変換した文字列の先頭文字FFFFFFFFを削除する

 

参考資料

.NET ネイティブによるアプリのコンパイル

https://msdn.microsoft.com/ja-jp/library/dn584397(v=vs.110).aspx

.NET Native とコンパイル

https://msdn.microsoft.com/ja-jp/library/dn807190(v=vs.110).aspx