在c ++中声明为const的数据会发生什么

时间:2011-04-28 08:32:33

标签: c++

当我们声明const变量时,在Bruce eckel书中说过发生常量折叠意味着没有为变量分配内存。

当我们将变量声明为const时会发生什么?

  1. 编译器如何自由优化const变量?
  2. 是否始终分配const个变量的内存,以及它可能不属于哪种情况?

3 个答案:

答案 0 :(得分:3)

编译器可以自由地优化const变量(以及其他任何东西),只要你无法区分程序的作用。

例如:

const int three = 3;
const int four = 4;

int f() { return three * four; }

这里编译器可以省略为变量分配存储空间,并且可能会产生与编写完全相同的代码return 12;

但是如果你取了three的地址,或者绑定了它的引用,或者将它声明为extern,那么编译器可能会被迫为它分配内存。

答案 1 :(得分:1)

我发现以下引用归因于Bruce Eckel的PDF:

  

const int bufsize = 100;您可以使用   bufsize编译器所在的任何地方   必须在编译时知道值。   编译器可以使用bufsize   执行恒定折叠,这意味着   编译器会减少一个复杂的   通过一个简单的表达式   执行必要的计算   在编译时。这是特别的   在数组定义中很重要:

假设你的意思是“不断折叠”而不是“记忆折叠”,他的意思是:

const int i = 10;
const int j = 20;
int k = i + j;

如果编译器可以证明这是唯一的使用时间,则不必为ij分配内存。在这种情况下,它可以用int k = 30;替换所有三行。由于变量标记为const,编译器可以自由地假设它们的值永远不会改变,并且它足够聪明,可以为您添加提前而不是等待运行时间。

对于它的价值,如果你还在学习语言,我不会太担心这个。它的实现细节;你通常可以指望它发生,但最终结果是相同的两种方式。编写有意义的代码,根据需要使用const来防止错误[作为节省内存的方法],如果编译器能够为您特别吐出一些东西,那么所有的更好。

-----------原始答案如下,因为它是一种相关主题

如果没有直接引用,我的猜测是他指的是这样的事情:

//in file 1:
const char* string1 = "Hello world!";
//in file 2:
const char* string2 = "Hello world!";
//in file 3:
const char* string3 = "world!";

在某些情况下,编译器/链接器能够发现string1string2都指向相同的字符串。因此,它不必创建包含相同数据的两个单独的字符串对象,assert(string1 == string2)最终会成功。更智能的设置可能会注意到string3是前两个的子字符串,最终会得到assert(string3 == string1+6)。在可执行文件的实际数据中,最终会得到一个字符串,即使在代码中有三个字符串。

在C ++中,它们const并不重要,因为您不能将非常量char*分配给字符串文字。但一般来说,如果允许三个字符串中的任何一个修改它们指向的内存,则该替换将无效。用户可能不打算*string1 = '5'更改*string2,因此在这种情况下不能压缩三个字符串。

答案 2 :(得分:0)

  

“表示没有为变量分配内存..”

你错了。如果它是一个变量(无论是const还是非const),它应该驻留在内存的某个部分。

当您将变量声明为const表示时,该变量的生命周期内无法修改。

const int num = 10 ;

num = 20 ; // Error : num cannot be modified. It is just a read only variable.

int var = 10 ;
var = 20 ;  // var is a modifiable integer variable.