http://www.perlmonks.org?node_id=1022443

ribasushi has asked for the wisdom of the Perl Monks concerning the following question:

Two questions in one really:
  • Did any version of perl ever build on a system with CHAR_BIT != 8?
  • If so - is there a way to find the value from *within perl itself* (i.e. no gcc, no Inline::C, no XS, etc)?

    Cheers!

  • Replies are listed 'Best First'.
    Re: CHAR_BIT != 8
    by tobyink (Canon) on Mar 08, 2013 at 15:45 UTC

      C99 says that CHAR_BIT must be at least 8; POSIX says it must be exactly 8; on Windows it's 8. That's about all the platforms it's worth caring about.

      Some DSPs use CHAR_BIT=16 or CHAR_BIT=32, but they're never going to run Perl anyway.

      How to get it? This is cheating I'm sure...

      use strict; use warnings; my $char_bit; open my $fh, "<", "/usr/include/limits.h"; while (<$fh>) { ($char_bit = $1, last) if /^#\s*define\s*CHAR_BIT\s*([0-9]+)/; } print "$char_bit\n";

      It's the kind of detail you might expect to be provided by Config, but no such luck :-(

      Update: meh... I wasn't looking hard enough...

      use strict; use warnings; use Config; print "$Config{charbits}\n";
      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
        Oh indeed. New Config piece starting from 5.12, this is why I didn't see it.
    Re: CHAR_BIT != 8
    by davido (Cardinal) on Mar 08, 2013 at 15:51 UTC

      This isn't addressing specifically how Perl is compiled, but rather how Perl implements the notion of characters: Because of Perl's Unicode implementation, a Perl character isn't necessarily a single byte. Consider the following:

      binmode STDOUT, ':encoding(utf8)'; my $cp = "\x{3a3}"; print "$cp\n"; # Prints an upper case sigma. print ord( $cp ), "\n"; # prints 931. print 0x00FF & ord( $cp ), "\n"; # prints 163. if( ord( $cp ) > 255 ) { print "Wide character.\n"; } if( ord( $cp ) != ( 0x00FF & ord( $cp ) ) ) { print "Wide character.\n"; }

      If you're not dropping into XS, what application is there for getting at the actual value of CHAR_BIT during compilation? (Just to satisfy my own curiosity, and to learn something new).

      Update: To be more clear in my final question: I do understand that the C implementation could possibly be compiled with CHAR_BIT != 8. We see checks for it within the XS code of Scalar::Vec::Util and Math::MPC, for example. But what I'm curious about is how it makes any difference from the perspective of a Perl script that doesn't use XS (aside from the potential that some XS modules will break because they're not checking like they should).


      Dave

        No particular reason other than completeness. I am adding a larger set of exportable constants to Devel::PeekPoke::Constants and wanted to be as thorough as possible ;)

        As far as why care about C stuff if you are not in C land - well again Devel::PeekPoke.

        Cheers

          Making Devel::PeekPoke::Constants more thorough is a great reason! :)


          Dave

    Re: CHAR_BIT != 8
    by Anonymous Monk on Mar 08, 2013 at 20:41 UTC
      $ perl "-V:.*?char.*?"
      charbits='8';
      d_charvspr='undef';
      stdchar='char';
    Re: CHAR_BIT != 8
    by ikegami (Patriarch) on Mar 09, 2013 at 18:39 UTC
      I doubt there ever was a version that worked with larger than 8-bit char. Current versions have known issues. There has been no demand or testing platform availability.
    Re: CHAR_BIT != 8
    by Anonymous Monk on Mar 08, 2013 at 20:07 UTC
      printf("%.0f bits\n",log(ord(~"\0")+1)/log(2));