C/C++ 对sizeof返回值类型不了解带来的陷阱

 对C/C++程序员来说,sizeof可以说再熟悉不过,sizeof是一个 C/C++中的运算符,在编译阶段计算并返回一个对象或数据类型所占用的内存大小(单位: 字节)。sizeof看起来简单,但是对它不了解很容易在代码中留下陷阱。比如:当传入一个表达式给sizeof时,它只会返回表达式计算结果的类型大小,但它不会对表达式求值。

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
int i = 2024;
std::cout << "sizeof(i++)=" << sizeof(i++) << std::endl;
std::cout << "i=" << i << std::endl; // i的值仍然是2024

return 0;
}

sizeof带来的陷阱还有许多,在此不做探讨,本文只举例最让人忽视的一种情况,下面这个程序的作者希望输出数组中的所有元素,运行后他却没有得到他想要的结果,程序没有输出任何内容,这是为什么呢?

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}

原因是sizeof的返回值类型是size_t,是一个无符号的整数。d为int类型,使用d与无符号整数比较时,d会被隐式类型转换为无符号整数。 这样就导致-1被转换成一个非常大的值,以至于for循环不满足条件。点击此处可以访问该程序作者的博客,他还有许多这种类似的陷阱程序。

结论:一定要切记sizeof返回的是无符号整数类型,当与有符号整数或其他类型进行比较,且这个有符号数的值可能为负数时,会带来不可预料的后果。