我们如何修改const变量的值?

时间:2018-07-23 01:24:22

标签: c++ const constants

“完整参考C ++”的第四版显示为“可以通过程序外部的内容来修改 const 类型的变量。例如,硬件设备可以设置其值。”

这是什么意思,如何实现?

3 个答案:

答案 0 :(得分:2)

有两种方式思考const的含义,或者换句话说,当您使用const限定词告诉编译器有关您的某些信息时,的含义代码。

第一个定义是,“此变量将永远不会更改,因此应将其放置在只读内存中。”

但是第二个定义是,“我不希望我的代码(或任何其他代码)会修改此变量,因此,如果我不小心尝试请警告我。”

那么问题是,如果您(无意间或其他原因)尝试更改const变量的值会怎样?然后,您要问的问题是,您将如何尝试?

如果实际上将const变量放置在只读存储器中,那么如果尝试对其进行修改,将会发生某种分段错误或总线错误。但是,如果它不在只读内存中(如果定义2起作用),并且尝试修改const变量,那么您将成功。

那么另一个问题是:它将如何改变?有很多可能性。

一种方法是作弊。如果你写类似

const int i = 5;
int *ip = (int *)&i;
*ip = 6;
printf("%d\n", i);

您很有可能成功将i更改为6。这是未定义的行为,并且不能保证能正常工作-绝对不应该将指针指向const ,请使用显式强制转换来清除常量,然后使用结果指针尝试更改值。因此,它可能无法工作-或可能。

另一种方法是在const后面做一些事情。假设您编写以下代码:

int j = 5;
const int *ip2 = &j;
printf("%d\n", *ip2);
j = 6;
printf("%d\n", *ip2);

在这种情况下,const是指针ip2指向的内容。在这里,定义2绝对适用:我们承诺要做的就是不修改ip2指向的内容。 (但是在这种情况下,const限定符不会将任何内容放入只读存储器中,因为ip2可以指向任何地方。)第二段代码没有错;甚至没有明确的演员表,更不用说粗略或非法的演员表了。如果我们试图说*ip2 = 6,编译器会(正确地)抱怨,但是在这种情况下,没有什么可以阻止我们(或其他一些代码段)更改j,但这确实意味着- -令人惊讶,令人惊讶-*ip2后面的值可以更改。

另一种可能性(尽管这再次有些粗略)是,在一个文件中声明了全局变量const,在另一个文件中声明了非常量。如果在文件1中,我们有

int g = 5;

在文件2中,我们有

extern const int g;

在文件1中,我们将g从5更改为6,然后在文件2中,当我们以为g不变时,看到这种变化可能会感到惊讶。

最后,我能想到的最后一种可能性是相当好奇的声明

const volatile int x;

变量同时为constvolatile是什么意思?好吧,const意味着该代码无法更改,但是volatile意味着它可能由于其他原因而更改。这将是描述只读机器寄存器的一种方式。这可能是本书所谈论的那种事情。

答案 1 :(得分:1)

如果const对象包含mutable个数据成员,则可以安全地修改它们。否则,在初始化后const对象的修改是未定义的行为。这样就可以使编译器具有使您的程序具有任意错误的权限。这是一个坏主意,您永远不要这样做。

现在您已经被警告,用const_cast来射击自己的脚。

原始消息来源可能说某些类型的对象可能会被系统上的某些其他硬件或软件修改。传统上,const volatile用于读取内存映射的硬件。某些设备驱动程序可能需要这样做。现代并行程序可能会在共享内存中使用原子变量,读取器线程无法修改原子变量,但是其他线程或进程会修改原子变量。

答案 2 :(得分:-1)

它只是说明const变量不必放在只读存储器中。您不能更改它(编译器将显示错误),但是可能的话可以。

您的问题

  

以及如何实现。

是错误的,因为可能会更改该值的内容不在您的控制之下。因此,您无法“实现”它。

如果const值未放置在RO内存中,则可能会更改它,并且某些东西(进程或硬件)可以更改此变量占用的内存位置。

由于您是一个初学者(并且在此阶段您不会编写多线程程序或设备驱动程序),因此您可能会完全忽略此注释。