我想证明没有什么叫做(受保护的内存地址),整个故事只是关于编译器、操作系统,或者宿主应用程序正在运行的任何应用程序,只需对托管的应用程序发送到其上级进程的读和写请求进行一些检查,或者这个高级应用程序或您所称的任何东西--它决定这个子进程是否有权对这个特定的内存位置进行读写,但是这个c++代码在本质上不能工作,所以为什么:
#include <iostream>
int main()
{
const int x = 10;
std::cout << &x << std::endl; // So i can view address of x
std::cout << "x Before is equal "<< x <<std::endl;
int y ;
std:: cin >> std::hex >>y;
int *pinter = (int*)y ;
*pinter = 20;
std::cout << "x After is equal "<< x <<std::endl;
}
这段代码应该绕过c++编译器将x变量类型设置为const int的概念,这样,指向变量的指针(在C中,指向常量的指针可以更改常量的值)和对变量的引用都不能更改变量,因此这段代码应该得到变量x的地址(当然在打印出来之后),然后指针完成其余的工作,所以我在这里做了什么,因为这个内存位置的接缝是硬件保护的(我知道它不是,但我很困惑)。
发布于 2020-06-03 00:58:21
这段代码应该绕过c++编译器将x变量类型设置为const的概念,以便.
您可以破坏语言的规则,但是您的代码是无效的C++。您不应修改限定为const
的内容。如果你这样做了,你就会有未定义的行为。因为编译器是用来编译有效的C++的,所以他们没有义务对非有效的代码做任何有意义的事情,结果可能是任何东西,也可能是什么都没有。
正如在评论中已经说过的:
const
与硬件或内存无关。这是你和你的编译器达成的协议,你违反了这个协议。作为一种奖励,编译器将对代码做任何事情,但不一定是您所期望的。
您试图欺骗编译器,在运行时进行修改,以便编译器在编译时无法知道您将修改const
。但是,您确实将x
声明为const
,因此编译器将假定其值不会更改。如果您仍然修改x
的值,任何事情都可能发生。
PS:人们经常想出一些方法来“喜欢”private
并不是真正的隐私,cosnt
并不是真正的const
和类似的东西。问题是:这些工具应该可以帮助您减少错误并编写更干净的代码。如果你试图绕过这些设施,你将设法做到这一点(有时甚至不调用UB)。然而,这种“预言”除了有可能射中自己的脚外,什么也没有。C++不是Java,它不握住你的手,试图防止你犯任何可能的错误。在这方面,C++更接近Pythons,“我们都是这里的成年人”。
发布于 2020-06-03 01:03:10
提供了以下内容: 1.注释不应该更改的值。2.允许编译器更好地优化代码,因为代码不应该更改。
你不需要跳过所有这些圈,你本可以用‘const_cast’来改变const‘’ness。
编译器“帮助”您执行const‘’ness,但是正如您所展示的,有许多方法可以绕过它。如果要更改const值,则会产生UB。
发布于 2020-06-03 02:04:38
它不能工作的原因(除了UB和编译器可能会优化代码,因为知道x
是const
)可能是因为如果您在64位系统上运行,int y
无法保存x
的地址。该地址最有可能是64位地址,其中一位是前32位的,而您的int
最有可能是32位。
使用正确的类型来存储地址并创建x
volatile const
,您将仍然拥有UB --但它可能就像您所期望的那样工作。
#include <cstdint>
#include <iostream>
int main()
{
volatile const int x = 10;
std::cout << "x Before is equal "<< x <<std::endl;
std::uintptr_t y = (std::uintptr_t) &x;
int *pinter = (int*) y;
*pinter = 20;
std::cout << "x After is equal "<< x <<std::endl;
}
https://stackoverflow.com/questions/62168728
复制