C++一些容易被忽视的points

| 2 Comments | No TrackBacks
今天又拿出尘封已久的BJ的The C++ Programming Language翻了翻,发现了一些容易被忽视、遗忘但有很重要的细节,记录在这里算是一个备忘吧。
  1. pointerbool类型之间存在implicit conversion。bool至少和char占用空间相同。
  2. 一个char 8位字符的value是从0到255还是从-127到+127是implementation-defined。但从0到127这部分是相同的。为了保证可移植性,赋值时尽量避免使用整型数值。
  3. Enumerator range。 每个enumerator的value都存在一个range。如果对其初始化或赋值时超出了这个range,结果是undefined。因此从integer到enumeration之间必须是explicit conversion。为了保证可移植性,要避免赋integral value时超出range的情况发生。Range的确定方法见p.77.
  4. 一个hidden global name可以通过::来引用,一个hidden local name无法被引用。
  5. string literal 的类型是const char[n+1],n是字符个数。例如,"hello" 的类型是 const char[6]。在从前版本C/C++中,string literal的类型是char*,为了兼顾从前的大量程序,把一个string literal赋值给char*依然有效,但是修改const 字串的结果是undefined。例如,char* pstr="hello"; pstr[1]='t';
  6. 从一个函数中返回string literal是安全的,因为给string literal分配的空间不会因为函数的返回而被释放。例如,return "hello";
  7. 两个完全相同的string literal 是否只有一份copy,是implementation-defined. 例如,char* pstr1 = "hello"; char* pstr2="hello"; pstr1是否等于pstr2由具体实现决定的。
  8. 两个指针相减只有在他们指向同一个数组时,结果才被defined。指针相加没有意义、不被允许。
  9. "plain" T&类型的initializer必须是Lvalue,const T&类型的initializer不必是Lvalue甚至不必是类型T(存在implicit type conversion)。例如,int& i = 1;(error) const int& i = 1; (OK,产生的临时变量一直存在知道i的scope结束)。
  10. pointers to function,pointers to members不能赋值给void*
  11. structure对象的大小未必是其member大小之和。
(To be updated)

No TrackBacks

TrackBack URL: http://lua.me/cgi-bin/mt/mt-tb.cgi/10

2 Comments

谢谢,很有用。原先只知道3、4、5、6这几点,7可能跟编译器的优化程度也有点关系,1和2仍然不是很明白。

关于11点,我曾经测试过,如果

struct A {};

cout

在Windows下为1,Linux下为0,呵呵,如果结构被对齐过,则值又不同了。

http://blog.ipattern.org/archives/281

Leave a comment

Recent Comments

  • 老所: 关于11点,我曾经测试过,如果 struct A {}; cout 在Windows下为1,Linux下为0,呵呵,如果结构被对齐过,则值又不同了。 http://blog.ipattern.org/archives/281 read more
  • 北极冰仔: 谢谢,很有用。原先只知道3、4、5、6这几点,7可能跟编译器的优化程度也有点关系,1和2仍然不是很明白。 read more