星期三, 八月 27, 2008

const char* const 的使用

以前代码里面一直这么写,也没有出什么问题,今天看了相关的讨论才发现这么做的问题。如下的例子:
header.h

const char* const gmsg = "ABC_DEF_GHI_JKL_XYZ";

void testfunc1();

void testfunc2();

 
cpp1.cpp

#include <iostream>

#include "header.h"

 

void testfunc1()

{

   std::cout << "msg from testfunc1:" << gmsg << '\n';

}

 

int main()

{

   testfunc1();

   testfunc2();

   return 0;

}

 
cpp2.cpp

#include<iostream>

#include "header.h"

void testfunc2()

{

   std::cout << "msg from testfunc2:" << gmsg << '\n';

}

然后我使用 VS2005 测试过程如下:
cl/EHsc cpp1.cpp cpp2.cpp
程序的执行结果没有任何问题,用记事本打开编译出来的 cpp1.exe,
搜索 ABC_DEF_GHI_JKL_XYZ 会发现有两份。
查询一下标准,原来 C++ 中 const 默认为内部链接的。
3.5
Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage
Rationale: Because const objects can be used as compile-time values in C + +, this feature urges programmers to provide explicit initializer values for each const.
 
因此有多少个编译单位就会有多少份 gmsg 的拷贝,对于 VC 可以采用编译选项,启用"字符串池"来避免这个问题的出现.虽然编译的 binary 没有大多少,但是还是采用如下的写法比较好,只有一份拷贝:
header.h

extern const char* const gmsg;

void testfunc1();

void testfunc2();

 
cpp1.cpp

#include <iostream>

#include "header.h"

const char* const gmsg = "ABC_DEF_GHI_JKL_XYZ";

void testfunc1()

{

   std::cout << "msg from testfunc1:" << gmsg << '\n';

}

 

int main()

{

   testfunc1();

   testfunc2();

   return 0;

}

 

cpp2.cpp

#include<iostream>

#include "header.h"

void testfunc2()

{

   std::cout << "msg from testfunc2:" << gmsg << '\n';

}

 

这样虽然在写的时候不是很舒服(代码提示的时候不能提示出来对应的字符串的内容),但是问题也不大习惯习惯就好了。
 
#END