Chinaunix首页 | 论坛 | 博客
  • 博客访问: 163993
  • 博文数量: 46
  • 博客积分: 2981
  • 博客等级: 少校
  • 技术积分: 475
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-01 12:43
文章分类

全部博文(46)

文章存档

2010年(4)

2009年(9)

2008年(33)

我的朋友

分类: C/C++

2009-09-02 20:22:41

关于sizeof的:
1、sizeof(i++)之后,i的值会怎样?答案是不变。记得大一初学C语言时想研究一下sizeof与函数有什么区别,得到的结果只是一些语法上的差别;学了汇编之后看看编译器生成的代码,才发现sizeof在编译时直接给定了一个常值,而非在运行时求值。进而又分析过sizeof(表达式)的结果,清楚了类型提升原理。但我之前没有注意过表达式中出现副作用的问题,于是在sizeof(i++)的问题上犹豫了。现在经过查阅资料和实验,结论是:sizeof在大多数情况下是编译时定值的,表达式中的任何副作用(包括有副作用的运算符、函数调用等)都不会发生。这里说“大多数情况”,排除了针对C99的新特性——不定长数组(variable length array)的特例。参考这篇文章(http://rednaxelafx.javaeye.com/blog/225909),如果sizeof运算符的参数是一个不定长数组,则该需要在运行时计算数组长度。
  2、sizeof(’a')的结果是多少?这个要看是在C中还是C++中了。根据标准的规定,在C的算术类型提升时,字符常量’a'自动提升为整型,故结果是4(对于32位机器);而在C++中则有字符常量的规定,’a'就是一个单字节的字符常量,故结果是1。我这样理解:C强调了char的“数”属性,而C++强调了char的“字符”属性。
  3、sizeof(’ab’)的结果又是多少?’ab’这种语法我以前没有注意到。经查,这叫做“多字节字符常量”(multi-character character constant),它限制在单引号中包含2至4个字节。根据标准,多字节字符常量的语义由编译器的实现决定。在我测试的gcc 4.0和VS2008中,如果int a = ‘abcd’,则a == 0×61626364。sizeof(’ab’) == sizeof(’abc’) == sizeof(’abcd’) == 4。
  4、那么sizeof(L’a')呢?虽然wchar_t是在源代码级可移植的宽字符,但其大小依赖于操作系统或编译器的定义。独立出现的wchar_t常量并不会像char常量那样做算术提升,所以sizeof(L’a')就等于sizeof(wchar_t)。在我在32位Windows和Linux平台下分别为2和4。
  5、至于sizeof(L’ab’)、sizeof(L’中’)、sizeof(L’中国’)又会如何?宽字符常量的单引号中出现多个字节构成的单个字符(如L’中’)是合法的,对它取sizeof,结果等于具体实现下的sizeof(wchar_t)。但出现多个字节构成的多个字符(如L’ab’、L’中国’)则是没有定义的,编译器可能报错,也可能给出不同的实现。在我测试的gcc4.0和VS2008中,L’abcd’分别返回了0×64和0×61。对它们取sizeof,结果等于具体实现下的sizeof(wchar_t),但注意这是标准未定义的,不应该确信。
C和C++处理register关键字的一处差异
用register关键字修饰的变量,在C语言中是不可以用&操作符取地址的。因为编译器如果接受了程序员的建议把变量存入寄存器,它是不存在虚拟地址的。但在C++中,用register修饰的变量可以用&操作符取地址,这是在一段代码中发现的。如果程序中显式取了register变量的地址,编译器一定会将这个变量定义在内存中,而不会定义为寄存器变量。
C99 :
The implementation may treat any register declaration simply as an auto declaration. However, whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary & operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1).
C++:
the hint
can be ignored and in most implementations it will be ignored if the address of the object is taken.
阅读(572) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~