是否可以在C++中使变量真正只读
Is it possible to make variable truly read-only in C++?
通过使用const
限定符,变量应该是只读的。例如,标记为const
的int
不能分配给:
const int number = 5; //fine to initialize
number = 3; //error, number is const
乍一看,这使得无法修改number
的内容。不幸的是,实际上它是可以做到的。作为示例,可以使用const_cast
(*const_cast<int*>(&number) = 3
)。这是未定义的行为,但这并不能保证number
实际上不会被修改。它可能会导致程序崩溃,但也可以简单地修改值并继续。
是否有可能使实际不可能修改变量?
可能的需要是出于安全考虑。最重要的可能是,某些非常有价值的数据不得更改,或者发送的数据不得修改。
不,这不是编程语言所关心的问题。任何";访问";保护只是表面的,只存在于编译时。
如果您拥有相应的权限,则可以在运行时修改计算机的内存。不过,您的操作系统可能会为您提供保护内存页的设施,例如Windows下的VirtualProtect()。
(请注意,"攻击者"如果有权限,可以使用相同的设施恢复访问)
此外,我认为可能有硬件解决方案。
还可以选择对有问题的数据进行加密。然而,这似乎是一个先有鸡后有蛋的情况,因为加密和解密的私钥也必须存储在内存中的某个地方(使用仅限软件的解决方案)。
虽然这个线程中的大多数答案都是正确的,但它们与const
有关,而OP正在寻求一种在源代码中定义和使用常数值的方法。我的水晶球说OP正在寻找符号常量(预处理器#define语句)。
#define NUMBER 3
//... some other code
std::cout<<NUMBER;
通过这种方式,开发人员能够参数化值并轻松维护它们,而一旦程序被编译和启动,几乎没有(简单的)方法来更改它。
请记住,常量变量对调试器可见,而符号常量则不可见,但它们不需要额外的内存。另一个标准是类型检查,这在符号常量和宏的情况下是不存在的。
const
不打算将变量设为只读
const x
的含义基本上是:
嘿,编译器,请防止我在这个范围内随意编写更改
x
的代码。
这与非常不同
嘿,编译器,请阻止在此范围内对
x
进行任何更改。
即使你自己不写任何const_cast
的,编译器仍然不会认为const
的实体不会改变。具体来说,如果您使用功能
int foo(const int* x);
编译器不能假设CCD_ 15不改变CCD_。
你可以在没有变量的情况下使用你的值
变量各不相同。。。因此,自然地,防止这种情况的一种方法是使用不存储在变量中的值。你可以通过使用。。。
- 具有单个值的枚举:
enum : int { number = 1 }
- 预处理器:CCD_ 18<-不推荐
- a函数:
inline int get_number() { return 1; }
您可以使用特定于实现/平台的功能
正如@SebastianHoffman所建议的,典型的平台允许将进程的一些虚拟内存空间标记为只读,因此试图更改它会导致进程的访问违规信号并暂停执行。这不是语言本身的解决方案,但它通常是有用的。示例:当您使用字符串文字时,例如:
const char* my_str = "Hello world";
const_cast<char*>(my_str)[0] = 'Y';
您的流程可能会失败,并显示以下消息:
Segmentation fault (core dumped)
如果您在编译时了解程序,则可以将数据放在只读内存中。当然,有人可以绕过这一点,但安全是关于层次而不是绝对的。这就更难了。C++对此没有概念,所以您必须检查生成的二进制文件,看看它是否发生了(这可以作为构建后检查编写)。
如果您在编译时没有该值,那么您的程序依赖于是否能够在运行时更改/设置它,因此您根本无法阻止这种情况的发生。
当然,你可以让它变得更难,尽管像const
这样的东西,所以代码是在假设它不会改变的情况下编译的/程序员不小心改变了它会更难。
您还可以在这里找到一个有趣的工具constexpr
。
没有办法指定哪些代码不符合规范。
在您的示例中,number
确实是恒定的。您正确地注意到,在const_cast
之后修改它将是未定义的beahvior。事实上,在正确的程序中修改它是不可能的。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 非常量变量只读位置的赋值
- 是否可以在C++中使变量真正只读
- C++代码中,只读变量不可分配
- 只读变量的赋值
- 在c++中将只读变量更改为目标
- 类的只读成员变量
- 在另一个函数/构造函数 [C++] 中初始化后使变量只读
- 多线程:我需要用只读方法保护我的变量吗
- 只读变量是不能赋值的c++模板函数
- 使用谷物序列化:只读第一个变量
- 只读变量赋值
- 在运行时赋值后为只读的变量
- 全局变量是只读的,并在 openmp 中"false sharing"写入私有类成员
- 只读变量不可赋值