2

Perl での整数オーバーフロー チェック (符号付き、符号なし、ビッグ エンディアン、リトル エンディアン) を使用して、式のさまざまな結果をパックしたいと考えています。私が試してみると:

$ perl -e 'use warnings; print pack("c", 200)' | hexdump -C

私は得る:

Character in 'c' format wrapped in pack at -e line 1.
00000000  c8                                                |.|
00000001

pack() 関数で発生した整数オーバーフローを確認する方法はありますか? または、関数がオーバーフローで失敗するように強制することはできますか? パッキングする前に各タイプ (符号付き 1、2、4、8 バイト、符号なし 1、2、4、8 バイト) の範囲をチェックすると、コードが少し醜いように見えます。

ありがとう。

4

2 に答える 2

4

「パック」警告カテゴリをオンにして、致命的にすることができます。次に、オーバーフローにより、トラップできる例外が発生します。例えば:

for my $val (127, 128) {
    print "$val -> ";
    if (eval {
        use warnings FATAL => qw(pack);
        pack("c", $val);
    }) {
        print "no overflow";
    } else {
        print "overflow ($@)";
    }
    print "\n";
}

もう 1 つの可能性は、(できればローカライズされた)$SIG{__WARN__}ハンドラーを使用し、警告が発生した場合にハンドラーをチェックインすることです。

于 2013-07-18T10:19:09.097 に答える
0

警告を致命的にするのが最も簡単な解決策ですが、独自のパッキング関数を作成することもできます。

use Carp         qw( croak );
use Scalar::Util qw( looks_like_number );

sub pack_uint32_be {
   my ($n) = @_;
   croak "Not a number" unless looks_like_number($n);
   croak "Overflow"     unless 0 < $n && $n <= 2**32;
   return pack 'L>', $n;
}

$packed .= pack_uint32_be($x);
$packed .= pack_uint32_be($y);
于 2013-07-18T13:42:22.683 に答える