Tuesday, October 14, 2008

Diff UNIX Windows, Part 2

平台的差异不仅表现在网络方面:

1)UNIX下create函数创建新文件通常用644作mode。而Windows没有group和other的概念,因此得用600。

2)中的isalpha、isprint、isprint等函数。
以isalpha为例,该函数可以判断给定的字符是否属于alphabet character。如果传给isalpha函数小于-1的char类型实参,程序执行时将出错。这是由isalpha函数中的Assert语句引发的:_ASSERTE((unsigned)(c + 1) <= 256); 该语句的作为用是保证参数的取值范围是0~255。

When used with a debug CRT library, isalpha will display a CRT assert if passed a parameter that is not EOF or in the range of 0 through 0xFF. When used with a release CRT library, isalpha will use the parameter as an index into an array, with undefined results if the parameter is not EOF or in the range of 0 through 0xFF.

------ MSDN


分析可知,出错的原因与两次类型转换有关:

isalpha函数的形参类型是int,而实参是char类型,因此c将首先被向上转型为int,即integral promotion。不同编译器对转型的实现可能不同,即有的将char看作有符号数,有的则看作无符号数。VC编译器属于前者,因此当传入的char类 型实参小于-1时,相应c+1的值小于0。

在Assert语句中,c+1被强制转换为无符号数,由于c+1是负数,因此转型后的值必大于256(负数的符号位为1)。

解决办法是在调用isalpha函数前先将char强制转型为unsigned char。推荐阅读《C Traps and Pitfalls》相关章节。

3)snprintf函数中对NULL结束符的处理。
int _snprintf( char *buffer, size_t count, const char *format [, argument] ... );

If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned.

------ MSDN


int snprintf ( char *str, size_t n, const char *format, ... );

It is similar to sprintf(3), except that n specifies the maximum number of characters to produce. The trailing null character i counted towards this limit, so you should allocate at least n characters for the string str.

------ man snprintf