昨天看的void的概念中提到了显式转换成为cv void.想起来转换,又没忍住翻到standard conversion.这一大坨隐式转换虽然可以让程序看上去简洁清爽,但是暗地里可是害了我不少次.有一次写从文件读写char类型数据的程序, 当时重载了读取/写入的函数,给出了 unsigned char 以及 int 两种类型的参数,当时写入的数据类型为char,想当然的以为应该是调用unsigned char.害的我调试了好久发现,实际调用的函数的参数类型是 int, 后来看标准才知道,原来char转换成为unsigned char 是属于 Integral conversions,匹配级别低于 Integral promotions ,也就是char转换成为 int. standard conversion 以及 overloading resolution 合起伙来涮了我一大把,哈哈.
在翻看C++ 98 标准的 standard conversion时,忽然扫到了一句话:
[4.1.2]The value contained in the object indicated by the lvalue is the rvalue result. When an lvalue-to-rvalue con-version occurs within the operand of sizeof (5.3.3) the value contained in the referenced object is not accessed, since that operator does not evaluate its operand.
想了半天也没有想明白这后半句的意思.哎呦,这个 左值到右值转换 咋就和 sizeof搭上边了呢,我咋连听都没有听过呢,为什么最后一句说:since that operator does not evaluate its operand , sizeof的操作数为啥就不会被计算呢.奇了怪了.
扭头继续翻看标准中对于sizeof的讲解:
[5.3.3.1] The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is not evaluated, or a parenthesized type-id .
啊!? sizeof 中的表达式竟然不会被计算.哇偶,这个,这个,这个是咋回事.学了那么多年C++,竟然连这个都不知道?!太丢脸了,实在是太丢脸了.[看官: 行了,行了,脸反正已经丢到家了,赶紧补漏被.]
写了一份代码做测试:
char i = 1;
mov byte ptr [i],1
size_t n = sizeof(i++);
mov byte ptr [i],1
printf(" i = %d, sizeof(i++) = %d ", i,n );
输出结果为 1,1. 果然 i++ 没有被计算.下面的汇编代码中表明,编译器并没有对sizeof进行计算,而是直接把1 mov 到了 n中.这说明了 sizeof 类似编译期行为,也就是在程序运行前就已经计算好了.我说sizeof怎么不会被计算呢.编译期行为当然不会被计算哦.
继续往下看标准,又看见了一条:
[5.3.3.4] The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not applied to the operand of sizeof.
5.3.3.4标准规定了 array-to-pointer 在sizeof中不能执行啊.