Const Correctness in C++

今天在翻阅<<The Exceptional Beauty of Doom 3's Source Code>>时, McGrath 和 John Carmack 无一提了"Const and Rigid Parameters".

参考: 

http://www.possibility.com/Cpp/const.html

####################################

Const With Pointers and Type-Casting


!!! 

With casting, you can force the compiler to let you put the address of a const int variable into a normal int*.



const int x = 4;           // x is const, it can't be modified
const int* pX = &x;        // you can't modify x through the pX pointer

cout << x << endl;         // prints "4"

int* pX2 = (int *)pX;      // explicitly cast pX as an int*
*pX2 = 3;                  // result is undefined

cout << x << endl;        // who knows what it prints?

在MS的编译器上,不论是否使用 const_cast, release/debug 结果都是4.

但是,如果是这样:

int x3 = *pX2 + 1;


那么,结果是 3.

为什么 ?

从反汇编的代码中可以看到,编译器对 cout 进行了优化.

但是,对 + 和 = 没有相同操作.

Const Storage and String Literals

string lieterals 大多是 static data,存储在 data segment, 但也有可能是在 .rodata 中.
1 A  string  literal  is  a  sequence  of  characters  (as  defined   in
  _lex.ccon_) surrounded by double quotes, optionally beginning with the
  letter L, as in "..." or L"...".  A string literal that does not begin
  with  L  is  an  ordinary string literal, also referred to as a narrow
  string literal.  An ordinary string literal has type "array of n const
  char"  and  static storage duration (_basic.stc_), where n is the size
  of the string as defined below, and  is  initialized  with  the  given
  characters.   A string literal that begins with L, such as L"asdf", is
  a wide string literal.  A wide string literal has  type  "array  of  n
  const wchar_t" and has static storage duration, where n is the size of
  the string as defined below, and is initialized with the given charac-
  ters.

2 Whether  all  string  literals  are  distinct  (that is, are stored in
  nonoverlapping objects)  is  implementation-defined.   The  effect  of
  attempting to modify a string literal is undefined.

如果是 .data, 那么是可以修改的.于是,就有了:

char* szMyString = "Hello world.";   
szMyString[3] = 'q';         // undefined, modifying static buffer!!!


If, as the standard says, an ordinary string literal has type "array of n const char", then the following line of code should cause an error just like the above example:
   // should be illegal - converts array of 6 const char to char*
   char* pArray = "Hello";

Of course, this code is a common idiom and it's perfectly legal. This appears to be an inconsistency in the language standard. A lot of these inconsistencies exist because older C and C++ code would break if the standard were strictly consistent. The standards people are afraid to break old code, because it would mean a decrease in the popularity of the language.

item 2 in the above quote from the language standard: literal strings don't have to be distinct. This means that it is legal for implementations to use string pooling, where all equal string literals are stored at the same place. For example, the help in Visual C++ states:

"The /GF option causes the compiler to pool strings and place them in read-only memory. By placing the strings in read-only memory, the operating system does not need to swap that portion of memory. Instead, it can read the strings back from the image file. Strings placed in read-only memory cannot be modified; if you try to modify them, you will see an Application Error dialog box. The /GF option is comparable to the /Gf option, except that /Gfdoes not place the strings in read-only memory. When using the /Gf option, your program must not write over pooled strings. Also, if you use identical strings to allocate string buffers, the /Gf option pools the strings. Thus, what was intended as multiple pointers to multiple buffers ends up as multiple pointers to a single buffer."
换句话讲:

(0)  multiple pointers to a single buffer 是完全可能的.

(1) 你最好打开 /Gf , 这样 "安全,省力"


Const and Data-Hiding

这个,才是最精彩的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值