GCC-3.4.6源代码学习笔记(171)
来源:互联网 发布:网络教育英语统考试题 编辑:程序博客网 时间:2024/06/04 18:58
5.13.5.2.2.1.1.3.3. 浮点数
与形式多样的整形常量不同,在C++的前端中,具有REAL_TYPE类型的常量只能是REAL_CST。
output_constant (continue)
3791 caseREAL_TYPE:
3792 if (TREE_CODE (exp) != REAL_CST)
3793 error ("initializer for floatingvalue is not a floating constant");
3794
3795 assemble_real(TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
3796 break;
有关浮点常量的内容,在创建浮点常量节点一节已经有详细的描述,这里不再重复。
1918 void
1919 assemble_real (REAL_VALUE_TYPEd, 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 intoan array of *host* longs, 32 bits per element
1927 (even if long ismore than 32 bits). We need to determine the
1928 number of arrayelements 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 mightappear at either end of the value; real_to_target
1935 will include thepadding 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 thefirst 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 wordsneed 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 }
上面1942行的real_to_target的核心是round_for_format函数,及与目标机器关联的real_format结构中的格式编码函数(通常是encode_ieee_single或encode_ieee_double)。
5.13.5.2.2.1.1.3.4. 字符串
字符串,在C/C++中,默认就被视为常量。其对应的节点是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 caseARRAY_TYPE:
3805 caseVECTOR_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 ((unsignedHOST_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 enummachine_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只是简单地封装了字符串,通过TREE_STRING_POINTER及TREE_STRING_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 isvery 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 }
为了避免汇编代码中对段长度的限制,每块字符串长度不超过2000个字符。下面的宏输出字符串的内容。在452行,STRING_LIMIT被定义为256。也就是说如果字符串(剩下)部分少于256个字符,就通过ASM_OUTPUT_LIMITED_STRING来输出,这个宏与这里的ASM_OUTPUT_ASCII很类似。在445及456行,输出的是字符“””并换行。可以想见,这个宏将输出形如:
“………”
“………”
的字符串。
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 (constunsigned char *) (STR); /
436 register const unsigned char *limit = _ascii_bytes + (LENGTH); /
437 registerunsigned bytes_in_chunk = 0; /
438 /
439 for (;_ascii_bytes < limit; _ascii_bytes++) /
440 { /
441 register constunsigned 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 registerint escape; /
466 registerunsigned 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 case0: /
474 putc (ch, (FILE)); /
475 bytes_in_chunk++; /
476 break; /
477 case1: /
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)
在469行,ASCII_DATA_ASM_OP被定义为“/t.ascii/t”。471行的ESCAPES是一个如下的字符串。
"/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"
它指定了如何输出对应的ASCII码的字母。
5.13.5.2.2.1.1.3.5. 聚集类初始值
如果聚集类型的存在初始值常量(初始值为空的情形由output_constant的3756行处理,参见全0的内容一节),则来到下面的代码中。
output_constant (continue)
3838 caseRECORD_TYPE:
3839 caseUNION_TYPE:
3840 if (TREE_CODE (exp) == CONSTRUCTOR)
3841 output_constructor(exp, size, align);
3842 else
3843 abort ();
3844 return;
3845
3846 caseSET_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 constructortype");
3860 return;
3861
3862 caseERROR_MARK:
3863 return;
3864
3865 default:
3866 abort ();
3867 }
3868
3869 if (size > thissize)
3870 assemble_zeros(size - thissize);
3871 }
前面我们看到CONSTRUCTOR节点在其CONSTRUCTOR_ELTS处保存了对应每个成员的初始值的tree_list链表。在这个链表的每个节点中,其TREE_VALUE域是初始值,其TREE_PURPOSE域,对于类类型是FIELD_DECL节点,对于数组类型则是索引。
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 bytesoutput or skipped so far.
3926 In other words, current position within theconstructor. */
3927 HOST_WIDE_INT total_bytes = 0;
3928 /* Nonzero meansBYTE 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 goesthrough the elements of the constant,
3943 FIELD goesthrough the structure fields, if the constant is a structure.
3944 if the constantis a union, then we override this,
3945 by getting thefield from the TREE_LIST element.
3946 But the constantcould also be an array. Then FIELD is zero.
3947
3948 There is always amaximum of one element in the chain LINK for unions
3949 (even if theinitializer 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 ina 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 themarker that makes a cast not be an lvalue. */
3979 if (val != 0)
3980 STRIP_NOPS(val);
注意在上面对于数组,变量field是NULL,它使用变量index;对于类类型则反之。在3980行,STRIP_NOPS将不影响汇编输出的封装(例如不需要产生代码的转换)去掉。
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 }
前端的节点RANGE_EXPR用于数组,表示一个范围的元素。例如,
int a [8] ={0};
其初始值就是一个RANGE_EXPR,表示在索引0到7的范围内使用初始值0。在上面的代码中可用看到,其第一个操作数是下限,而第二个操作数则是上限。在C++中,RANGE_EXPR的初始值只可能是0。
满足下面4003行条件的节点是:数组(field为NULL)、非位域的类成员。变量pos保存了初始值所应用的位置。对于类成员,由于已经完成布局,4010行的int_byte_position通过调用byte_position获得其相对类头的偏移。对于数组,元素大小x索引跨度,就可以得到其到数组头的偏移(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 thiselement. */
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 isguaranteed
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 initializerdetermines the size. */
4044 /* ??? This ought to only checked if DECL_SIZE_UNIT isNULL,
4045 but we cannot dothis until the deprecated support for
4046 initializingzero-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 anon-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'tbe right. If the decl size overflows
4060 a host integer we will silently emit nodata. */
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 }
变量total_bytes记录着已初始化的大小。对于类,C++要求按成员声明的次序初始化(前端在布局时亦按照声明次序),因此如果出现pos不等于total_bytes的情况,则表明pos与total_bytes之间是一个填充域。按标准要求,用0填充之。对于数组,因为元素大小一致,元素之间不需要填充域,若pos不等于total_bytes,则表明这部分元素的初始值没有给出,根据标准,需初始化为0。在4018行,变量byte_buffer_in_use来自下面位域初始值的处理。
那么下面的代码就是对类中位域成员初始值的处理。首先,其初始值必须是整型常量,4077行条件保证这一点。另外,位域与其之前的域之间亦可能有填充域,在4098行完成这个填充。
output_constructor (continue)
4077 else if (val != 0 && TREE_CODE(val) != INTEGER_CST)
4078 error ("invalid initial value formember `%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 beprocessed.
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 whennecessary. */
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 thesame byte). */
4141 this_time = MIN (end_offset -next_offset,
4142 BITS_PER_UNIT - next_bit);
4143 if (BYTES_BIG_ENDIAN)
4144 {
4145 /* On big-endianmachine, take the most significant bits
4146 first (of thebits that are significant)
4147 and put theminto bytes from the most significant end. */
4148 shift = end_offset - next_offset - this_time;
4149
4150 /* Don't try totake a bunch of bits that cross
4151 the word boundary in the INTEGER_CST. We can
4152 only select bitsfrom the LOW or HIGH part
4153 not fromboth. */
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 bitsfrom 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-endianmachines,
4181 take first theleast significant bits of the value
4182 and pack themstarting at the least significant
4183 bits of thebytes. */
4184 shift = next_offset - int_bit_position(field);
4185
4186 /* Don't try totake a bunch of bits that cross
4187 the wordboundary in the INTEGER_CST. We can
4188 only select bitsfrom 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 bitsfrom 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 }
上面的变量next_offset是这个位域的偏移(单位是比特),变量end_offset则记录着这个位域所要占用的内存的末尾(注意这个占用的内存可能多于一个字节,因此需要4122行的WHILE循环)。记得在类布局中(参见GCC默认布局下的位域及MS布局下的位域一节)多个位域可能将共享同一块内存,因此我们只写入整字节的数据,还没占满整字节的数据保存在byte中,并由byte_buffer_in_use指示。又因为多个位域可以共享同一块内存,那么在写入它们共同形成的比特位图(也就是数值)时,就有“大小头”(big-endian,little-endian)的考量。比如:
char a:2;
char b:3;
char c:3;
如果除了a的初始值为1外,其他都是0,那么在小头(little-endian)机器上,我们需要向这个字节写入1,而在大头(big-endian)机器上,则是128。因此还要根据宏BYTES_BIG_ENDIAN的定义分别处理。对于x86/Linux,这个宏定义为0,是小头机器。
- GCC-3.4.6源代码学习笔记(171)
- GCC-3.4.6源代码学习笔记 (100)
- GCC-3.4.6源代码学习笔记 (101)
- GCC-3.4.6源代码学习笔记 (102)
- GCC-3.4.6源代码学习笔记 (103)
- GCC-3.4.6源代码学习笔记 (104)
- GCC-3.4.6源代码学习笔记 (105)
- GCC-3.4.6源代码学习笔记 (106)
- GCC-3.4.6源代码学习笔记(166)
- GCC-3.4.6源代码学习笔记
- GCC-3.4.6源代码学习笔记(6)
- GCC-3.4.6源代码学习笔记(1)
- GCC-3.4.6源代码学习笔记(2)
- GCC-3.4.6源代码学习笔记(3)
- GCC-3.4.6源代码学习笔记(4)
- GCC-3.4.6源代码学习笔记(5)
- GCC-3.4.6源代码学习笔记(7)
- GCC-3.4.6源代码学习笔记(8)
- 关于架构
- 水文过程线(一)
- c++代码在不同编译器之间的移植的小故事 - 循环变量
- 在WindowsMobil系统中实现透明树组件
- Boost::Regex使用
- GCC-3.4.6源代码学习笔记(171)
- 为系统添加root用户密码
- Studying note of GCC-3.4.6 source (171)
- argus.py 可以仍是昔日素心悠游的少年
- MapReduce流程分析
- 上拉电阻下拉电阻的总结(转载经典)
- 使用RMA进行分离合并rmvb音频、视频文件
- windows下巧用SFTP打造安全传输~
- Android游戏开发起步(译文)