#gcc -g -O2 idr.c -o idr
=======================================
#include
#include
struct idr {
unsigned long id_word[10];
};
struct idr idr = {{0}};
int alloc_id()
{
int i, j;
int bit = sizeof(idr.id_word[0]) * 8;
for (i = 0; i < 10; i++) {
for (j = 0; j < bit; j++) {
if (!(idr.id_word[i] & (1UL << j))) {
idr.id_word[i] |= (1UL << j);
return i * bit + j;
}
}
}
return -1;
}
void remove_id(int id)
{
int i, bit;
i = id / (sizeof(idr.id_word[0]) * 8);
bit = id % (sizeof(idr.id_word[0]) * 8);
idr.id_word[i] &= ~(1UL << bit);
}
int main(void)
{
int i;
int id1, id2, id3;
for (i = 0; i < 10 * sizeof(idr.id_word[0]) * 8 + 1; i++) {
printf("[%d]id = %d\n", i, alloc_id());
}
remove_id(15);
remove_id(67);
remove_id(129);
printf("%d, %d, %d\n", alloc_id(), alloc_id(), alloc_id());
return 0;
}
=======================================
先说说x86 -64 Linux上的输出结果:
...
[638]id = 638
[639]id = 639
[640]id = -1
129, 67, 15
然后是powerpc 64bit AIX上的输出结果:
...
[318]id = 318
[319]id = 319
[320]id = -1
15, 67, 129
同是gcc,同样的命令行,同是64bit OS,结果真的不一样 unsigned long在64bit的aix上怎么就成了4字节了?哦,原来是powerpc gcc缺省的工作模式就是32bit,为了让它工作在64bit模式上,得用-maix64这个FLAG, #gcc -g -O2 -maix64 size.c -o size 之后就成了:
...
[638]id = 638
[639]id = 639
[640]id = -1
15, 67, 129
从输出结果看, 最后那一行应该不是C标准,而是compiler自己定义的行为,不同平台下的gcc对printf里参数的计算结果(即本例中是函数alloc_id调用的次序,从左到右还是相反)的实现方式并不一样。
另外,如果把程序中的1UL改写成1,又是另一个结果了(当idr.id_word[0]=0x7FFFFFFF时,idr.id_word[0] |= (1 << 31)将导致idr.id_word[0]=0xFFFFFFFFFFFFFFFF)