为什么允许使用memcpy使用指向它的指针覆盖const变量? [英] Why is it allowed to overwrite a const variable using a pointer to it using memcpy?

查看:187
本文介绍了为什么允许使用memcpy使用指向它的指针覆盖const变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么允许通过memcpy使用指向它的指针来更改const变量?

Why is it allowed to change a const variable using a pointer to it with memcpy?

此代码:

const int i=5;
int j = 0;
memcpy(&j, &i, sizeof(int));
printf("Source: i = %d, dest: j = %d\n", i,j);

j = 100;
memcpy(&i, &j, sizeof(int));
printf("Source: j = %d, dest: i = %d\n", j,i);
return 0;

仅编译警告:

警告:传递"memcpy"的参数1会丢弃"const"限定词 来自指针目标类型[默认启用]

warning: passing argument 1 of ‘memcpy’ discards ‘const’ qualifier from pointer target type [enabled by default]

但是运行得很好,并更改了const变量的值.

But did run just fine, and changed the value of a const variable.

推荐答案

问题问为什么.原因如下:

之所以允许这样做,是因为一旦有了指向内存地址的指针,该语言就不会知道它指向的内容.它可以是变量,结构,堆或堆栈的一部分,或其他任何东西.因此,它不能阻止您对其进行写操作.直接内存访问始终是不安全的,如果有其他方法可以避免.

This is allowed because once you have a pointer to a memory address, the language does not know what it points to. It could be a variable, part of a struct, the heap or the stack, or anything. So it cannot prevent you from writing to it. Direct memory access is always unsafe and to be avoided if there's another way of doing it.

const停止您使用赋值(或增量等)修改const的值.这种变异是唯一可以确保您无法在const上执行的操作.

The const stops you modifying the value of a const with an assignment (or increment etc). This kind of mutation is the only operations it can guarantee you won't be able to perform on a const.

查看此问题的另一种方法是将静态上下文(即在编译时)和运行时上下文进行划分.当您编译一段代码(例如,可能对一个变量赋值)时,该语言可能会说这是不允许的,它是const",这是编译错误.此后,代码被编译成可执行文件,并且它是const的事实丢失了.变量声明(以及语言的其余部分)被作为对编译器的输入来编写.编译后,代码就不相关了.您可以在编译器中进行逻辑证明,说const不变.编译后的程序开始运行,我们在编译时就知道我们创建了一个不违反规则的程序.

Another way to look at this is the division of the static context (i.e. at compile time) and the runtime context. When you compile a piece of code which may, for example, make an assignment to a variable, the language can say "that's not allowed, it's const" and that is a compilation error. After this, the code is compiled into an executable and the fact that it is a const is lost. Variable declarations (and the rest of the language) is written as input to the compiler. Once it is compiled, the code isn't relevant. You can do a logical proof in your compiler to say that consts aren't changed. The compiled program runs, and we know at compile time that we have created a program that doesn't break the rules.

引入指针时,您可以在运行时定义行为.您编写的代码现在无关紧要,您可以[尝试]做您想做的事情.键入指针的事实(允许进行指针算术,将指针末尾的内存解释为特定类型)意味着该语言为您提供了一些帮助,但不能阻止您执行任何操作.它无法保证,因为您可以将指针指向任何地方.编译器无法阻止您在运行时使用使用指针的代码来违反规则.

When you introduce pointers, you have behaviour that can be defined at run-time. The code that you wrote is now irrelevant, and you can [attempt to] do what you want. The fact that pointers are typed (allowing pointer arithmetic, interpreting the memory at the end of a pointer as a particular type) means that the language gives you some help, but it can't prevent you from doing anything. It can make no guarantees, as you can point a pointer anywhere. The compiler can't stop you breaking the rules at run-time with code that uses pointers.

也就是说,指针是我们获取动态行为和数据结构的方式,除了最琐碎的代码外,指针是所有指针所必需的.

That said, pointers are the way we get dynamic behaviour and data structures, and are necessary for all but the most trivial code.

(以上内容有很多警告,即代码启发式,更复杂的静态分析总线大致适用于原始编译器.)

(The above is subject to lots of caveats, i.e. code heuristics, more sophisticated static analysis bus is broadly true of a vanilla compiler.)

这篇关于为什么允许使用memcpy使用指向它的指针覆盖const变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆