Studying note of GCC-3.4.6 source (171)

5.13.5.2.2.1.1.3.3.            Floating point

Not like variant integer constants there, in C++ front-end, constant of REAL_TYPE type can only be REAL_CST.

 

output_constant (continue)

 

3791     case REAL_TYPE:

3792       if (TREE_CODE (exp) != REAL_CST)

3793         error ("initializer for floating value is not a floating constant");

3794

3795       assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);

3796       break ;

 

The detail about floating point constant has been covered in section Create node for real constant , we would not repeat here again.

 

1918 void

1919 assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)

1920 {

1921   long data[4];

1922   int i;

1923   int bitsize, nelts, nunits, units_per;

1924

1925   /* This is hairy. We have a quantity of known size. real_to_target

1926     will put it into an array of *host* longs, 32 bits per element

1927     (even if long is more than 32 bits). We need to determine the

1928     number of array elements that are occupied (nelts) and the number

1929     of *target* min-addressable units that will be occupied in the

1930     object file (nunits). We cannot assume that 32 divides the

1931     mode's bitsize (size * BITS_PER_UNIT) evenly.

1932

1933     size * BITS_PER_UNIT is used here to make sure that padding bits

1934     (which might appear at either end of the value; real_to_target

1935     will include the padding bits in its output array) are included.  */

1936

1937   nunits = GET_MODE_SIZE (mode);

1938   bitsize = nunits * BITS_PER_UNIT;

1939   nelts = CEIL (bitsize, 32);

1940   units_per = 32 / BITS_PER_UNIT;

1941

1942   real_to_target (data, &d, mode);

1943

1944   /* Put out the first word with the specified alignment.  */

1945   assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1);

1946   nunits -= units_per;

1947

1948   /* Subsequent words need only 32-bit alignment.  */

1949   align = min_align (align, 32);

1950

1951   for (i = 1; i < nelts; i++)

1952   {

1953     assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);

1954     nunits -= units_per;

1955   }

1956 }

 

Above at line 1942, the kernel of real_to_target is function round_for_format , and the format encoding function in structure real_format associating with the target machine (generally is encode_ieee_single or encode_ieee_double ).

5.13.5.2.2.1.1.3.4.            Literal string

Literal string, in C/C++, is treated as constant by default, it is built with node STRING_CST.

 

output_constant (continue)

 

3798     case COMPLEX_TYPE:

3799       output_constant (TREE_REALPART (exp), thissize / 2, align);

3800       output_constant (TREE_IMAGPART (exp), thissize / 2,

3801                     min_align (align, BITS_PER_UNIT * (thissize / 2)));

3802       break ;

3803

3804     case ARRAY_TYPE:

3805     case VECTOR_TYPE:

3806       if (TREE_CODE (exp) == CONSTRUCTOR)

3807       {

3808         output_constructor (exp, size, align);

3809         return ;

3810       }

3811       else if (TREE_CODE (exp) == STRING_CST)

3812       {

3813         thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp),

3814                       size);

3815         assemble_string (TREE_STRING_POINTER (exp), thissize);

3816       }

3817       else if (TREE_CODE (exp) == VECTOR_CST)

3818       {

3819         int elt_size;

3820         tree link;

3821         unsigned int nalign;

3822         enum machine_mode inner;

3823

3824         inner = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (exp)));

3825         nalign = MIN (align, GET_MODE_ALIGNMENT (inner));

3826

3827         elt_size = GET_MODE_UNIT_SIZE (TYPE_MODE (TREE_TYPE (exp)));

3828

3829         link = TREE_VECTOR_CST_ELTS (exp);

3830         output_constant (TREE_VALUE (link), elt_size, align);

3831          while ((link = TREE_CHAIN (link)) != NULL)

3832             output_constant (TREE_VALUE (link), elt_size, nalign);

3833       }

3834       else

3835         abort ();

3836       break ;

 

STRING_CST just encuplsates literal string simply, by TREE_STRING_POINTER and TREE_STRING_LENGTH can fetch the string and its length.

 

1190 void

1191 assemble_string (const char *p, int size)                                                      in varasm.c

1192 {

1193   int pos = 0;

1194   int maximum = 2000;

1195

1196   /* If the string is very long, split it up.  */

1197

1198   while (pos < size)

1199   {

1200     int thissize = size - pos;

1201     if (thissize > maximum)

1202       thissize = maximum;

1203

1204     ASM_OUTPUT_ASCII (asm_out_file , p, thissize);

1205

1206     pos += thissize;

1207     p += thissize;

1208   }

1209 }

 

To avoid violating the limitation of section size, every block is not larger than 2000 characters. Below macro output the string. At line 452, STRING_LIMIT is defined as 256. That is if the string (or the left part) is less than 256 characters, it is output by ASM_OUTPUT_LIMITED_STRING, this macro is quite similar with ASM_OUTPUT_ASCII here. At line 445 and 456, it outputs character ” and breaks the line. Conceivable, the macro will output like this:

“………”

“………”

 

430  #undef   ASM_OUTPUT_ASCII

431  #define ASM_OUTPUT_ASCII (FILE, STR, LENGTH)                           /      in elfos.h

432    do                                                                /

433      {                                                             /

434        register const unsigned char *_ascii_bytes =                 /

435              (const unsigned char *) (STR);                                /

436        register const unsigned char *limit = _ascii_bytes + (LENGTH);   /

437        register unsigned bytes_in_chunk = 0;                          /

438                                                                 /

439        for (; _ascii_bytes < limit; _ascii_bytes++)                    /

440        {                                                  /

441           register const unsigned char *p;                        /

442                                                                 /

443           if (bytes_in_chunk >= 60)                                /

444           {                                                      /

445             fprintf ((FILE), "/"/n");                                 /

446             bytes_in_chunk = 0;                              /

447           }                                                      /

448                                                                 /

449           for (p = _ascii_bytes; p < limit && *p != '/0'; p++)           /

450             continue ;                                              /

451                                                                 /

452           if (p < limit && (p - _ascii_bytes) <= (long)STRING_LIMIT)  /

453           {                                                      /

454             if (bytes_in_chunk > 0)                                 /

455            {                                           /

456                fprintf ((FILE), "/"/n");                       /

457               bytes_in_chunk = 0;                                  /

458            }                                           /

459                                                                 /

460             ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes);        /

461             _ascii_bytes = p;                                          /

462           }                                                      /

463            else                                                  /

464           {                                                      /

465             register int escape;                                 /

466             register unsigned ch;                              /

467                                                                 /

468             if (bytes_in_chunk == 0)                               /

469              fprintf ((FILE), "%s/"", ASCII_DATA_ASM_OP);             /

470                                                                 /

471             switch (escape = ESCAPES[ch = *_ascii_bytes])          /

472            {                                           /

473              case 0:                                              /

474                 putc (ch, (FILE));                                 /

475                 bytes_in_chunk++;                                /

476                 break ;                                    /

477               case 1:                                              /

478                 fprintf ((FILE), "//%03o", ch);                /

479                 bytes_in_chunk += 4;                                   /

480                 break ;                                    /

481              default :                                      /

482                 putc ('//', (FILE));                                 /

483                 putc (escape, (FILE));                           /

484                 bytes_in_chunk += 2;                                   /

485                 break ;                                    /

486            }                                           /

487           }                                                      /

488        }                                                  /

489                                                                 /

490        if (bytes_in_chunk > 0)                                        /

491          fprintf ((FILE), "/"/n");                              /

492      }                                                             /

493    while (0)

 

At line 469, ASCII_DATA_ASM_OP is defined as “/t.ascii/t”, and ESCAPES at line 471 is the string below.

"/1/1/1/1/1/1/1/1btn/1fr/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/

/0/0/"/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/

/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0///0/0/0/

/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/1/

/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/

/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/

/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/

/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1"

It indicates who to output the corresponding ASCII character.

5.13.5.2.2.1.1.3.5.            For aggregate type

If aggregate type has initializer (the case of empty initializer is handled at line 3756 in output_constant , refers to section Content of 0 ), it comes into below code.

 

output_constant (continue)

 

3838     case RECORD_TYPE:

3839     case UNION_TYPE:

3840       if (TREE_CODE (exp) == CONSTRUCTOR)

3841         output_constructor (exp, size, align);

3842       else

3843         abort ();

3844       return ;

3845

3846     case SET_TYPE:

3847       if (TREE_CODE (exp) == INTEGER_CST)

3848         assemble_integer (expand_expr (exp, NULL_RTX,

3849                                    VOIDmode, EXPAND_INITIALIZER),

3850                        thissize, align, 1);

3851        else if (TREE_CODE (exp) == CONSTRUCTOR)

3852       {

3853         unsigned char *buffer = alloca (thissize);

3854         if (get_set_constructor_bytes (exp, buffer, thissize))

3855           abort ();

3856         assemble_string ((char *) buffer, thissize);

3857       }

3858       else

3859         error ("unknown set constructor type");

3860       return ;

3861

3862     case ERROR_MARK:

3863       return ;

3864

3865     default :

3866       abort ();

3867   }

3868

3869   if (size > thissize)

3870     assemble_zeros (size - thissize);

3871 }

 

In previous, we have seen that in CONSTRUCTOR node, its CONSTRUCTOR_ELTS is a tree_list containing initializer for every member. In every node in this list, the TREE_VALUE field is the initializer, and TREE_PURPOSE field, for class type is FIELD_DECL node, while for arrary type, is the index.

 

3918 static void

3919 output_constructor (tree exp, unsigned HOST_WIDE_INT size,                            in varasm.c

3920                  unsigned int align)

3921 {

3922   tree type = TREE_TYPE (exp);

3923   tree link, field = 0;

3924   tree min_index = 0;

3925   /* Number of bytes output or skipped so far.

3926     I n other words, current position within the constructor.  */

3927   HOST_WIDE_INT total_bytes = 0;

3928   /* Nonzero means BYTE contains part of a byte, to be output.  */

3929   int byte_buffer_in_use = 0;

3930   int byte = 0;

3931

3932   if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)

3933     abort ();

3934

3935   if (TREE_CODE (type) == RECORD_TYPE)

3936     field = TYPE_FIELDS (type);

3937

3938   if (TREE_CODE (type) == ARRAY_TYPE

3939       && TYPE_DOMAIN (type) != 0)

3940     min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));

3941

3942   /* As LINK goes through the elements of the constant,

3943     FIELD goes through the structure fields, if the constant is a structure.

3944     if the constant is a union, then we override this,

3945     by getting the field from the TREE_LIST element.

3946     But the constant could also be an array. Then FIELD is zero.

3947

3948     There is always a maximum of one element in the chain LINK for unions

3949     (even if the initializer in a source program incorrectly contains

3950     more one).  */

3951   for (link = CONSTRUCTOR_ELTS (exp);

3952        link;

3953        link = TREE_CHAIN (link),

3954        field = field ? TREE_CHAIN (field) : 0)

3955   {

3956     tree val = TREE_VALUE (link);

3957     tree index = 0;

3958

3959     /* The element in a union constructor specifies the proper field

3960       or index.  */

3961     if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE

3962           || TREE_CODE (type) == QUAL_UNION_TYPE)

3963         && TREE_PURPOSE (link) != 0)

3964       field = TREE_PURPOSE (link);

3965

3966     else if (TREE_CODE (type) == ARRAY_TYPE)

3967       index = TREE_PURPOSE (link);

3968

3969 #ifdef ASM_COMMENT_START

3970     if (field && flag_verbose_asm )

3971       fprintf (asm_out_file , "%s %s:/n",

3972             ASM_COMMENT_START,

3973             DECL_NAME (field)

3974                ? IDENTIFIER_POINTER (DECL_NAME (field))

3975                : "<anonymous>");

3976 #endif

3977

3978     /* Eliminate the marker that makes a cast not be an lvalue.  */

3979     if (val != 0)

3980       STRIP_NOPS (val);

 

Note that above for array, variable field is NULL, it uses variable index instead; vice verse for class type. At line 3980, STRIP_NOPS strips the encuplsations not affecting the assemble output (for instance conversion needs not code generated).

 

output_constructor (continue)

 

3982     if (index && TREE_CODE (index) == RANGE_EXPR)

3983     {

3984       unsigned HOST_WIDE_INT fieldsize

3985           = int_size_in_bytes (TREE_TYPE (type));

3986        HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0);

3987       HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0);

3988       HOST_WIDE_INT index;

3989       unsigned int align2 = min_align (align, fieldsize * BITS_PER_UNIT);

3990

3991       for (index = lo_index; index <= hi_index; index++)

3992       {

3993         /* Output the element's initial value. */

3994         if (val == 0)

3995           assemble_zeros (fieldsize);

3996          else

3997           output_constant (val, fieldsize, align2);

3998

3999         /* Count its size.  */

4000         total_bytes += fieldsize;

4001       }

4002     }

 

The front-end node RANGE_EXPR is used for array, to represent elements within a range. For example,

int a [8] = {0};

whose initializer is a RANGE_EXPR, stands for using value 0 within range from index 0 to 7. In above, can see that, its first operand is the lower limit, and the second operand is the upper one. In C++, initializer in RANGE_EXPR can only be 0.

Nodes satisfying condition at line 4003 below are: array (field is NULL), non-bit-field member. Variable pos holds the position the initializer applied. For class member, as the layout has been done, int_byte_position at line 4010 invokes byte_position to get the offset to the class head. For array, by element size x index span, can get the offset to the array head (line 4014).

 

output_constructor (continue)

 

4003      else if (field == 0 || !DECL_BIT_FIELD (field))

4004     {

4005       /* An element that is not a bit-field.  */

4006

4007       unsigned HOST_WIDE_INT fieldsize;

4008       /* Since this structure is static,

4009         we know the positions are constant.  */

4010       HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;

4011       unsigned int align2;

4012

4013       if (index != 0)

4014         pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)

4015               * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0)));

4016

4017       /* Output any buffered-up bit-fields preceding this element.  */

4018       if (byte_buffer_in_use)

4019       {

4020         assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);

4021         total_bytes++;

4022         byte_buffer_in_use = 0;

4023       }

4024

4025       /* Advance to offset of this element.

4026         Note no alignment needed in an array, since that is guaranteed

4027         if each element has the proper size.  */

4028       if ((field != 0 || index != 0) && pos != total_bytes)

4029       {

4030         assemble_zeros (pos - total_bytes);

4031         total_bytes = pos;

4032       }

4033

4034       /* Find the alignment of this element.  */

4035       align2 = min_align (align, BITS_PER_UNIT * pos);

4036

4037       /* Determine size this element should occupy.  */

4038       if (field)

4039       {

4040         fieldsize = 0;

4041

4042         /* If this is an array with an unspecified upper bound,

4043           the initializer determines the size.  */

4044         /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,

4045           but we cannot do this until the deprecated support for

4046            initializing zero-length array members is removed.  */

4047         if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE

4048            && TYPE_DOMAIN (TREE_TYPE (field))

4049            && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))

4050          {

4051           fieldsize = array_size_for_constructor (val);

4052           /* Given a non-empty initialization, this field had

4053              better be last.  */

4054           if (fieldsize != 0 && TREE_CHAIN (field) != NULL_TREE)

4055             abort ();

4056         }

4057            else if (DECL_SIZE_UNIT (field))

4058         {

4059           /* ??? This can't be right. If the decl size overflows

4060             a host integer we will silently emit no data.  */

4061           if (host_integerp (DECL_SIZE_UNIT (field), 1))

4062             fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);

4063         }

4064       }

4065       else

4066         fieldsize = int_size_in_bytes (TREE_TYPE (type));

4067

4068       /* Output the element's initial value.  */

4069       if (val == 0)

4070         assemble_zeros (fieldsize);

4071       else

4072         output_constant (val, fieldsize, align2);

4073

4074       /* Count its size.  */

4075       total_bytes += fieldsize;

4076     }

 

Variable total_bytes records the size of the part initialized. For class, C++ requires to initialize members in order of declaration (the front-end does the layout by that order), so if pos doesn’t equate to total_bytes , it means between pos and total_bytes is an area need padding. By standard, it should be padded with 0. For array, as elements are of the same size, there is no padding area between elements, if pos doesn’t equate to total_bytes , it means elements within the range aren’t given, and by standard, it should be initialized by 0. At line 4018, variable byte_buffer_in_use comes from bit-field handling below.

Thus below code is the treatment of bit-field in class. First, its initializer must be an integer constant, condition at line 4077 ensures this. Besides, between the bit-field and the field ahead, it may be a padding area, line 4098 finishes this padding.

 

output_constructor (continue)

 

4077     else if (val != 0 && TREE_CODE (val) != INTEGER_CST)

4078       error ("invalid initial value for member `%s'",

4079             IDENTIFIER_POINTER (DECL_NAME (field)));

4080     else

4081     {

4082       /* Element that is a bit-field.  */

4083

4084       HOST_WIDE_INT next_offset = int_bit_position (field);

4085       HOST_WIDE_INT end_offset

4086           = (next_offset + tree_low_cst (DECL_SIZE (field), 1));

4087

4088       if (val == 0)

4089         val = integer_zero_node;

4090

4091       /* If this field does not start in this (or, next) byte,

4092         skip some bytes.  */

4093       if (next_offset / BITS_PER_UNIT != total_bytes)

4094       {

4095         /* Output remnant of any bit field in previous bytes.  */

4096         if (byte_buffer_in_use)

4097         {

4098           assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);

4099           total_bytes++;

4100           byte_buffer_in_use = 0;

4101         }

4102

4103         /* If still not at proper byte, advance to there.  */

4104         if (next_offset / BITS_PER_UNIT != total_bytes)

4105         {

4106           assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);

4107           total_bytes = next_offset / BITS_PER_UNIT;

4108         }

4109       }

4110

4111       if (! byte_buffer_in_use)

4112         byte = 0;

4113

4114       /* We must split the element into pieces that fall within

4115         separate bytes, and combine each byte with previous or

4116         following bit-fields.  */

4117

4118       /* next_offset is the offset n fbits from the beginning of

4119         the structure to the next bit of this element to be processed.

4120         end_offset is the offset of the first bit past the end of

4121         this element.  */

4122       while (next_offset < end_offset)

4123       {

4124         int this_time;

4125         int shift;

4126         HOST_WIDE_INT value;

4127         HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;

4128         HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;

4129

4130         /* Advance from byte to byte

4131           within this element when necessary.  */

4132         while (next_byte != total_bytes)

4133         {

4134           assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);

4135           total_bytes++;

4136           byte = 0;

4137         }

4138

4139         /* Number of bits we can process at once

4140           (all part of the same byte).  */

4141         this_time = MIN (end_offset - next_offset,

4142                        BITS_PER_UNIT - next_bit);

4143         if (BYTES_BIG_ENDIAN)

4144         {

4145           /* On big-endian machine, take the most significant bits

4146             first (of the bits that are significant)

4147              and put them into bytes from the most significant end.  */

4148           shift = end_offset - next_offset - this_time;

4149

4150           /* Don't try to take a bunch of bits that cross

4151              the word boundary in the INTEGER_CST. We can

4152             only select bits from the LOW or HIGH part

4153             not from both.  */

4154           if (shift < HOST_BITS_PER_WIDE_INT

4155               && shift + this_time > HOST_BITS_PER_WIDE_INT)

4156           {

4157             this_time = shift + this_time - HOST_BITS_PER_WIDE_INT;

4158             shift = HOST_BITS_PER_WIDE_INT;

4159           }

4160

4161           /* Now get the bits from the appropriate constant word.  */

4162           if (shift < HOST_BITS_PER_WIDE_INT)

4163              value = TREE_INT_CST_LOW (val);

4164           else if (shift < 2 * HOST_BITS_PER_WIDE_INT)

4165           {

4166             value = TREE_INT_CST_HIGH (val);

4167             shift -= HOST_BITS_PER_WIDE_INT;

4168           }

4169           else

4170              abort ();

4171

4172           /* Get the result. This works only when:

4173             1 <= this_time <= HOST_BITS_PER_WIDE_INT.  */

4174           byte |= (((value >> shift)

4175                   & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))

4176                        << (BITS_PER_UNIT - this_time - next_bit));

4177         }

4178         else

4179         {

4180           /* On little-endian machines,

4181             take first the least significant bits of the value

4182             and pack them starting at the least significant

4183             bits of the bytes.  */

4184           shift = next_offset - int_bit_position (field);

4185

4186           /* Don't try to take a bunch of bits that cross

4187             the word boundary in the INTEGER_CST. We can

4188             only select bits from the LOW or HIGH part

4189              not from both.  */

4190           if (shift < HOST_BITS_PER_WIDE_INT

4191               && shift + this_time > HOST_BITS_PER_WIDE_INT)

4192             this_time = (HOST_BITS_PER_WIDE_INT - shift);

4193

4194           /* Now get the bits from the appropriate constant word.  */

4195           if (shift < HOST_BITS_PER_WIDE_INT)

4196             value = TREE_INT_CST_LOW (val);

4197           else if (shift < 2 * HOST_BITS_PER_WIDE_INT)

4198           {

4199             value = TREE_INT_CST_HIGH (val);

4200             shift -= HOST_BITS_PER_WIDE_INT;

4201           }

4202           else

4203             abort ();

4204

4205           /* Get the result. This works only when:

4206             1 <= this_time <= HOST_BITS_PER_WIDE_INT.  */

4207           byte |= (((value >> shift)

4208                  & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))

4209                      << next_bit);

4210         }

4211

4212          next_offset += this_time;

4213         byte_buffer_in_use = 1;

4214       }

4215     }

4216   }

4217

4218   if (byte_buffer_in_use)

4219   {

4220     assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);

4221     total_bytes++;

4222   }

4223

4224   if ((unsigned HOST_WIDE_INT)total_bytes < size)

4225     assemble_zeros (size - total_bytes);

4226 }

 

Above variable next_offset is the offset of this bit-field (in bits), and variable end_offset records the tail of the memory the bit-field will occupy (see that the bit-field may need more than 1 byte memory, so it needs WHILE loop at line 4122). Remember in class layout (refer to section Alignment – bit field in GCC layout and Alignment – bit field in MS layout ) several bit-fields can share the memory, as we only write data by bytes, data can’t fill one byte is cached by byte , and is told by byte_buffer_in_use . And as several bit-fields can share memory, when output them in form of bit pattern (in fact the value), it should given consideration about big-endian and little-endian. For example:

char a:2;

char b:3;

char c:3;

If except the initializer of a is 1, others are 0, then in little-endian machine, we should write the byte with 1, while on big-endian machine, it is 128. So it should be treated differently according to the definition of BYTES_BIG_ENDIAN. For x86/Linux, the macro is defined as 0, it is a little-endian machine.

 

你可能感兴趣的:(String,tree,Integer,byte,Constructor,output)