C++ 在C+;中是否可以使变量真正只读+;?

C++ 在C+;中是否可以使变量真正只读+;?,c++,constants,C++,Constants,通过使用const限定符,变量应该是只读的。例如,标记为const的int不能分配给: const int number = 5; //fine to initialize number = 3; //error, number is const 乍一看,这似乎使修改number的内容变得不可能。不幸的是,事实上这是可以做到的。例如,可以使用const\u cast(*const\u cast(&number)=3)。这是未定义的行为,但这并不保证数字实际上不会被修改。它可能会导致程序崩溃,但

通过使用
const
限定符,变量应该是只读的。例如,标记为
const
int
不能分配给:

const int number = 5; //fine to initialize
number = 3; //error, number is const
乍一看,这似乎使修改
number
的内容变得不可能。不幸的是,事实上这是可以做到的。例如,可以使用
const\u cast
*const\u cast(&number)=3
)。这是未定义的行为,但这并不保证
数字
实际上不会被修改。它可能会导致程序崩溃,但也可能只是修改值并继续

是否有可能使修改变量实际上变得不可能


这可能需要考虑安全问题。某些非常有价值的数据不能被更改,或者发送的数据不能被修改,这可能是最重要的。

不,这与编程语言无关。任何“访问”保护都只是表面的,只存在于编译时

如果您具有相应的权限,则在运行时始终可以修改计算机内存。不过,您的操作系统可能会为您提供保护内存页的功能,例如在Windows下

(请注意,“攻击者”可以使用相同的工具来恢复访问权限(如果他有此权限的话)

我还假设可能有硬件解决方案


还可以选择对相关数据进行加密。然而,这似乎是一种鸡和蛋的情况,因为加密和解密的私钥也必须存储在内存中的某个位置(使用纯软件解决方案)。

如果您在编译时知道该程序,则可以将数据放在只读内存中。当然,有人可以绕过这一点,但安全性是关于层次的,而不是绝对的。这让事情变得更难。C++没有这个概念,所以你必须检查结果二进制文件,看看它是否发生了(这可以被脚本化为后编译检查)。 如果您在编译时没有该值,那么您的程序取决于能否在运行时更改/设置它,因此您根本无法阻止这种情况的发生

当然,您可以通过
const
之类的事情使它变得更难,因此编译代码时假设代码不会更改/程序员意外更改代码会更难

您还可以在这里找到一个有趣的工具
constepr

const
并不是要使变量成为只读的。
const x
的含义基本上是:

嘿,编译器,请防止我在这个范围内随意编写代码,这会改变
x

这与:

嘿,编译器,请防止在此范围内对
x
进行任何更改

即使您自己没有编写任何
const\u cast
,编译器也不会假定
const
”实体不会更改。具体来说,如果您使用该函数

int foo(const int* x);
编译器不能假定
foo()
不会更改
x
指向的内存

您可以在不使用变量的情况下使用您的值 变量不同。。。因此,很自然地,一种防止这种情况的方法是使用不存储在变量中的值。你可以通过使用

  • 具有单个值的枚举:
    enum:int{number=1}

  • 预处理器:
    #定义编号1
    无法指定哪些代码不符合规范


    在您的示例中,
    number
    确实是常量。您正确地注意到,在
    const_cast
    之后修改它将是未定义的beahvior。实际上,在一个正确的程序中修改它是不可能的。

    虽然此线程中的大多数答案都是正确的,但它们与
    常量相关,而OP正在寻求一种在源代码中定义和使用常量值的方法。我的水晶球说OP正在寻找符号常量(预处理器#define语句)

    #定义数字3
    //... 其他代码
    
    库特诺。即使变量存储在RO内存中或直接编码在指令中,也可以轻松地临时使内存R/W并更改值/指令。或者只是修补程序集以从其他地方加载值。或这么多的可能性。C++让你的腿被踢掉。这是您访问低级内容所付出的代价。如果您可以使用
    #define
    将其用作常量。@Imran A
    #define
    不是变量。是的,它不是变量,但可以用作常量constant@NathanOliver:是的,我会解决这个问题。事实上,
    const
    可以在不同的上下文中使用,const对象(因此只有
    mubable
    字段可以更改)和常量别名(通过引用或指针)(在常量或非常量对象上)。前者不能在没有UB的情况下修改,后者可以通过别名间接修改为非常量(可能由
    const\u cast
    创建)。
    const char* my_str = "Hello world";
    const_cast<char*>(my_str)[0] = 'Y';
    
    Segmentation fault (core dumped)
    
    #define NUMBER 3
    //... some other code
    std::cout<<NUMBER;