C语言 我们可以通过指针改变用 const 定义的对象的值吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3801557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we change the value of an object defined with const through pointers?
提问by Shweta
#include <stdio.h>
int main()
{
const int a = 12;
int *p;
p = &a;
*p = 70;
}
Will it work?
它会起作用吗?
回答by Crashworks
It's "undefined behavior," meaning that based on the standard you can't predict what will happen when you try this. It may do different things depending on the particular machine, compiler, and state of the program.
这是“未定义的行为”,这意味着根据标准,您无法预测尝试此操作时会发生什么。根据特定的机器、编译器和程序的状态,它可能会做不同的事情。
In this case, what will most often happen is that the answer will be "yes." A variable, const or not, is just a location in memory, and you can break the rules of constness and simply overwrite it. (Of course this will cause a severe bug if some other part of the program is depending on its const data being constant!)
在这种情况下,最常发生的是答案是“是”。变量,无论是否为常量,都只是内存中的一个位置,您可以打破常量规则并简单地覆盖它。(当然,如果程序的其他部分依赖于其常量数据,这将导致严重的错误!)
However in some cases -- most typically for const staticdata -- the compiler may put such variables in a read-only region of memory. MSVC, for example, usually puts const static ints in .text segment of the executable, which means that the operating system will throw a protection fault if you try to write to it, and the program will crash.
然而,在某些情况下——最常见的是const static数据——编译器可能会将这些变量放在内存的只读区域中。例如,MSVC 通常将 const static int 放在可执行文件的 .text 段中,这意味着如果您尝试写入它,操作系统将抛出保护错误,并且程序将崩溃。
In some other combination of compiler and machine, something entirely different may happen. The one thing you canpredict for sure is that this pattern will annoy whoever has to read your code.
在编译器和机器的其他组合中,可能会发生完全不同的事情。您可以确定的一件事是,这种模式会惹恼任何必须阅读您的代码的人。
回答by JeremyP
It's undefined behaviour. Proof:
这是未定义的行为。证明:
/* program.c */
int main()
{
const int a = 12;
int* p;
p = &a;
*p = 70;
printf("%d\n", a);
return 0;
}
gcc program.c
and run it. Output will be 70 (gcc 4.3)
并运行它。输出将为 70 (gcc 4.3)
Then compile it like this:
然后像这样编译它:
gcc -O2 program.c
and run it. The output will be 12. When it does optimisation, the compiler presumably loads 12 into a register and doesn't bother to load it again when it needs to access a for the printf because it "knows" that a can't change.
并运行它。输出将是 12。当它进行优化时,编译器可能会将 12 加载到寄存器中,并且在需要访问 printf 的 a 时不会费心再次加载它,因为它“知道” a 不能更改。
回答by Michael Foukarakis
Modifying a constqualified object through a pointer invokes undefined behaviour, and such is the result. It may be something you'd expect from a particular implementation, e.g. the previous value unchanged, if it has been placed in .text, etc.
const通过指针修改限定对象会调用未定义的行为,这就是结果。它可能是您期望从特定实现中获得的东西,例如,先前的值不变,如果它已被放置在 中.text,等等。
回答by Alexander Sagen
It does indeed work with gcc. It didn't like it though:
它确实适用于 gcc。但它不喜欢它:
test.c:6: warning: assignment discards qualifiers from pointer target type
test.c:6: 警告:赋值会丢弃来自指针目标类型的限定符
But the value did change when executed. I won't point out the obvious no-no...
但是执行时该值确实发生了变化。我不会指出明显的不...
回答by Jokester
yes, you can make it done by using such code. but the code do not apply when when ais global (a gcc-compiled program gave me segmentation fault.)
是的,你可以通过使用这样的代码来完成。但是代码在 whena是全局的时候不适用(一个 gcc 编译的程序给了我segmentation fault。)
generally speaking, in beloved C, you can almost always find someway to hack things that are not supposed to be changed or exposed. const here being a example.
一般来说,在心爱的 C 中,你几乎总能找到一些方法来破解不应该改变或暴露的东西。const 这里是一个例子。
But thinking about the poor guy(maybe myself after 6 months) maintains our code, I often choose not do so.
但是想想那个可怜的家伙(也许是我 6 个月后)维护我们的代码,我经常选择不这样做。
回答by Hemant
Here the type of pointer pis int*, which is being assigned the value of type const int*(&a=> address of a const intvariable).
这里指针的类型p是int*,它被分配了类型的值const int*(&a=>const int变量的地址)。
Implicit cast eliminates the constness, though gcc throws a warning (please note this largely depends on the implementation).
尽管 gcc 会抛出警告(请注意,这在很大程度上取决于实现),但隐式强制转换消除了常量性。
Since the pointer is not declared as a const, value can be changed using such pointer.
由于指针未声明为 a const,因此可以使用此类指针更改值。
if the pointer would be declared as const int* p = &a, you won't be able to do *p = 70.
如果将指针声明为const int* p = &a,您将无法执行*p = 70。
回答by M.M
This code contains a constraint violation:
此代码包含违反约束:
const int a = 12;
int *p;
p = &a;
The constraint violated is C11 6.5.16.1/1 "Simple assignment"; if both operands are pointers then the type pointed to by the left must have all the qualifiers of the type pointed to by the right. (And the types, sans qualifiers, must be compatible).
违反的约束是 C11 6.5.16.1/1 "Simple assignment"; 如果两个操作数都是指针,则左侧指向的类型必须具有右侧指向的类型的所有限定符。(并且类型,无限定符,必须兼容)。
So the constraint is violated because &ahas type const int *, which has constas a qualifier; but that qualifier does not appear in the type of pwhich is int *.
因此违反了约束,因为&a有 type const int *,它const作为限定符;但该限定符没有出现在pis的类型中int *。
The compiler must emit a diagnostic and might not generate an executable. The behaviour of any executable would be completely undefined, since the program does not comply with the rules of the language.
编译器必须发出诊断信息,并且可能不会生成可执行文件。任何可执行文件的行为都是完全未定义的,因为程序不符合语言规则。
回答by 3Dave
Bad, BAD idea.
坏,坏主意。
Also, the behavior is platform- and implementation-specific. If you're running on a platform where the constant is stored in non-writable memory, this obviously won't work.
此外,该行为是特定于平台和实现的。如果您在常量存储在不可写内存中的平台上运行,这显然不起作用。
And, why on earth would you want to? Either update the constant in your source, or make it a variable.
而且,你到底为什么想要?要么更新源中的常量,要么使其成为变量。
回答by Abhijeet Pathak
You cannot change the value of a constant variable by using a pointer pointing to it. This type of pointer is called as Pointer to a constant.
不能通过使用指向常量变量的指针来更改常量变量的值。这种类型的指针称为Pointer to a constant。
There is also another concept called Constant Pointer. It means that once a pointer points to a memory location you cannot make it point to the another location.
还有一个概念叫做Constant Pointer。这意味着一旦一个指针指向一个内存位置,你就不能让它指向另一个位置。
回答by M. HASHIM
Yes, you can change the value of a constant variable.
Try this code:
是的,您可以更改常量变量的值。
试试这个代码:
#include <stdio.h>
int main()
{
const int x=10;
int *p;
p=(int*)&x;
*p=12;
printf("%d",x);
}

