数値オーバーフローに関するこの回答で指摘された後、調査を行ったところ、QVariant の変換ルーチンに欠陥があるようです。QVariant を安全に変換する最も簡単な方法は、代わりに QString の変換を使用することです。これは、16 進文字列で QVariant を使用する最も簡単な方法のようにも思えます。以下に調査結果をまとめました。コメントはqDebug() << v;
、コードのその時点で を呼び出した結果の出力になります。
シナリオ 1: 数値を 16 進文字列として格納する
v = QVariant("0xBEEF"); // 'QVariant(QString, "0xBEEF") '
v = v.toString().toInt(0, 16); // 'QVariant(int, 48879) '
v = QVariant("0xDEADBEEF"); // 'QVariant(QString, "0xDEADBEEF") '
v = v.toString().toInt(0, 16); // 'QVariant(int, 0) '
10 進数を表す文字列を数値型に変換する最も簡単で安全な方法は、QString のtoInt(bool * ok = 0, int base = 10)
メソッドを使用することです。
シナリオ 2: 数値を 10 進文字列として格納
v = QVariant("123456"); // 'QVariant(QString, "123456") '
v.convert(QVariant::Int); // 'QVariant(int, 123456) '
QVariant のconvert(Type t)
メソッドは、このシナリオで期待どおりに機能します。
v = QVariant("2147483649"); // 'QVariant(QString, "2147483649") '
v.convert(QVariant::Int); // 'QVariant(int, -2147483647) '
v = QVariant("9223372036854775807"); // 'QVariant(QString, "9223372036854775807") '
v.convert(QVariant::Int); // 'QVariant(int, -1) '
ただし、文字列にデータ型に対して大きすぎる数値が含まれている場合に同じ方法を使用すると、false を返して QVariant を 0 に設定するなどのより便利なことを行う代わりに、サイレント オーバーフローが発生します。
v = QVariant("2147483649"); // 'QVariant(QString, "2147483649") '
v = v.toString().toInt(); // 'QVariant(int, 0) '
v = QVariant("9223372036854775807"); // 'QVariant(QString, "9223372036854775807") '
v = v.toString().toInt(); // 'QVariant(int, 0) '
シナリオ 1 と同じ方法を使用することで、これが発生するのを防ぐことができます。また、オプションの*bool
パラメーターを使用してtoInt()
障害を警告することもできます。