http://qs321.pair.com?node_id=11126919


in reply to hex numbers

The 0xNNNN notation is a source-code feature. It is parsed at compile-time. So this works:

my $n = 0xDEADBEEF; print "$n\n"; # Output: # 3735928559

And this works but you shouldn't use it:

# This works but is NOT recommended, and can be unsafe. my $n = eval "0xDEADBEEF"; print "$\n"; # Output: # 3735928559

That second example works because even though we've created a string of characters, "0xDEADBEEF", the eval statement evaluates that string as source code, so it gets parsed and compiled when the statement is executed at runtime.

This doesn't work:

my $n = "0xDEADBEEF"; print "$n\n"; # Output: # 0xDEADBEEF

It didn't work because the string was taken as plain old characters. Since you want to take a string of characters and interpret them as a hex digits you should use the hex function:

This is the version you should use:

my $string = "DEADBEEF"; my $n = hex($string); print "$n\n"; # Output: # 3735928559

Dave

Replies are listed 'Best First'.
Re^2: hex numbers
by shmem (Chancellor) on Jan 14, 2021 at 18:06 UTC
    And this works but you shouldn't use it:
    # This works but is NOT recommended, and can be unsafe. my $n = eval "0xDEADBEEF"; print "$\n"; # Output: # 3735928559

    It is not unsafe. "0xDEADBEEF" is a string constant. It is just as if 0xDEADBEEF had been put into the source code at the first place, with the difference that the literal is evaluated at compile time, whereas eval "0xDEADBEEF"; is evaluated at run time. Neither of them is safer than the other.

    String eval is not unsafe per se - but it is unsafe if applied upon strings of dubious provenience. Every piece of perl code (which is a bunch of strings) is eval-ed by the perl binary.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      I'm certainly aware that many modules even do this:

      our $VERSION = "1.2.3_001"; $VERSION = eval $VERSION;

      As documented in perlmodstyle, I think. The specific code I used in the example isn't unsafe. But the evaluation of a string can be unsafe if the string's source isn't well controlled. And if the original poster were able to hard code hex, he could do so using 0x literals. Since he's not using 0x literals, I assume that's because the hex strings are coming from somewhere external. And at that point the caveats about evaluating strings apply.

      But you're correct. What I posted isn't inherently unsafe. The practice is inherently easy to make unsafe, though.


      Dave

        The practice is inherently easy to make unsafe, though.

        This is true. I should have posted the following rewrite of your example

        # This works but is NOT recommended, and can be unsafe. my $s = "0xDEADBEEF"; # here we assign from a constant - but where # does the value come from in your code? my $n = eval $s; print "$n\n"; # Output: # 3735928559

        which makes that point clear. It is not the eval of a string constant, hard coded into a program which is unsafe, but eval'ing a string from elsewhere.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      It is not unsafe.

      davido didn't say that: "This works but is NOT recommended, and can be unsafe", and at least to me it's obvious that this refers to what you said:

      it can be unsafe if used upon strings of dubious provenience

      If one is doing eval, one is usually using it on strings based on user input or dynamically generated strings, otherwise one wouldn't have to eval in the first place!

      Stringy eval is one of those "only do this if you really know what you are doing" type of things, so while your clarification certainly isn't wrong, I also think warning against it is absolutely the right thing.

        davido didn't say that: "This works but is NOT recommended, and can be unsafe", and at least to me it's obvious that this refers to what you said

        Using string eval on a proper hex string constant can not be unsafe. While warning aubout string eval composed of user input or some such is appropriate, it is not for this construct. Warnings should be correct. Saying to a girl "if you kiss that boy you'll get pregnant!" is, albeit often turning out true in the long run, incorrect and misleading. Hence my comment.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'