8 你又做假定了吗?
有时在编程序时,有必要对程序的运行环境做出某些假定。但这并不是说在编程序时,
总要对运行环境做出假定。
1)
/* memset ─── 用 byte的值填充内存 */
void* memset(void* pv,byte b, size_t size)
{
byte* pb = (byte*)pv;
while(size-- > 0)
*pb++ = b;
return(pv);
}
2)
/* longfill ─── 用 long的值填充内存块在填完了最后一个长字之后
* 返回一个指向所填第一个长字的指针
*/
long* longfill(long* pl, long l, size_t size); /* 原型 */
memset(void* pv, byte b, size_t size)
{
byte* pb = (byte*)pv;
if(size >= sizeThreshold)
{
unsigned long l;
l = (b<<8) | b; /* 用 4 个字节拼成一个长字 */
l = (l<<16) | l;
pb = (byte*)longfill((long*)pb, l, size/4);
size = size%4;
}
while(size-- > 0)
*pb++ = b;
return(pv);
}
对 sizeThreshold进行测试是为了使memset 只有在用 long进行填充速度更快时才进行相应的填充。否则就仍用 byte 进行填充。
这个 memset新版本的唯一问题是它对编译程序和操作系统都做了一些假定。例如这段代码很明显地假定 long占用四个内存字节,该字节的宽度是八位。
3)
某些程序员“改进”这一程序的方法,是把它写成下面这种可移植性更好的形式:
memset(void* pv, byte b, size_t size)
{
byte* pb = (byte*)pv;
if(size >= sizeThreshold)
{
unsigned long l;
size_t sizeSize;
l = 0;
for(sizeSize=sizeof(long); sizeSize-->0; NULL)
l = (l<<CHAR_BIT) | b;
pb = (byte*)longfill((long*)pb, l, size/sizeof(long));
size = size%sizeof(long);
}
while(size-- > 0)
*pb++ = b;
return(pv);
}
由于在程序中大量使用了运算符 sizeof,这个程序看起来移植性更好,但“看起来”不等于“就是”。如果要把它移到新的环境中还是要对其进行考察才行。
4)
至于对程序中所做的其他假定,可以利用断言和条件编译进行相应的验证:
memset(void* pv, byte b, size_t size)
{
byte* pb = (byte*)pv;
#ifdef MC680x0
if(size >= sizeThreshold)
{
unsigned long l;
ASSERT(sizeof(long)==4 && CHAR_BIT==8);
ASSERT(sizeThreshold>=3);
/* 用字节进行填充直到对齐在长字边界上 */
while( ((unsigned long)pb & 3) != 0 )
{
*pb++ = b;
size--;
}
/* 现在拼装长字并用长字填充其他内存单元 */
l = (b<<8) | b; /* 用 4 个字节拼成一个长字 */
l = (l<<16) | l;
pb = (byte*)longfill((long*)pb, l, size/4);
size = size%4;
}
#endif /* MC680x0 */
while(size-- > 0)
*pb++ = b;
return(pv);
}
消除所做的隐式假定或者利用断言检查其正确性
9 光承认编译程序还不够
最近Microsoft的一些小组渐渐发现他们不得不对其代码进行重新的考察和整理,因为相当多的代码中充满了“+2”而不是“+sizeof(int)”、与 0xFFFF而不是 UINT_MAX 进行无符号数的比较、在数据结构中使用的是 int而不是真正想用的 16 位数据类型这一类问题。
为了在 Intel 80386和更新的处理器上生成更快更小的程序,编译程序组改变了 int 的
大小(以及其他一些方面)。虽然编译程序组并不想使公司内部的代码垮掉,但是保持在市场上的竞争地位显然更重要。毕竟,这是那些自己做了错误假定的 Microsoft程序员的过错。
转载请注明原创连接:http://blog.csdn.net/wujunokay/article/details/17802175