如何修改const变量的值?(复制)

时间:2022-05-20 23:38:40

This question already has an answer here:

这个问题已经有了答案:

I am able to change the value of const modified variable in gcc but not in other compilers. I have tried this code on gcc, which updates the value of i and j (11). With an online compiler, I get different values.

我可以更改gcc中const修饰变量的值,但不能更改其他编译器中的值。我在gcc上试用了这段代码,它更新了I和j(11)的值。使用在线编译器,我可以得到不同的值。

#include<stdio.h>
void main() {
  const int i=10;
  int *j;
  j = &i;
  (*j)++;
  printf("address of j is %p address of i is %p\n",j,&i);
  printf("i is %d and j is %d\n",i,*j);
}

5 个解决方案

#1


12  

Yes, you can do it with a little hack.

是的,你可以用一点技巧。

#include <stdio.h>
int main(){
    const int a = 0;
    *(int *)&a = 39;
    printf("%d", a);
}

In the above code, a is a const int. With the little hack, you can change the constant value.

在上面的代码中,a是一个const int.通过这个小技巧,您可以更改常量值。

Update: Explanation

更新:解释

In the above code, a is defined as a const. For example a has a memory addr 0x01 and therefore &a returns the same. When it is casted with (int *) it becomes another variable referred as a pointer to the const. When it is accessed with * again, the another variable can be accessed without violation of the const policy because it is not the original variable, but the changes are reflected because it is referred as address to the pointer.

在上面的代码中,a被定义为const。例如,a有一个内存addr 0x01,因此&a也返回相同的结果。当它被(int *)赋值时,它就变成了另一个变量,称为指向const的指针。当它再次被*访问时,可以不违反const策略地访问另一个变量,因为它不是原始的变量,而是因为它被称为指针的地址而反映了这些变化。

This will work on older versions like Borland C++ or Turbo C++, however no one is using it now a days.

这将适用于较老的版本,如Borland c++或Turbo c++,但是现在已经没有人使用它了。

It's "undefined behaviour", 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 const 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!)

在这种情况下,最常见的情况是,答案将是“是”。变量const或not只是内存中的一个位置,您可以打破const的规则,简单地覆盖它。(当然,如果程序的其他部分依赖于常量的const数据,这将导致严重的错误!)

However in some cases -- most typically for const static data -- 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静态数据——编译器可能会将这些变量放在内存的只读区域中。例如,MSVC通常将静态ints放在可执行文件的.text段中,这意味着如果您试图写入操作系统将抛出保护错误,程序将崩溃。

In some other combination of compiler and machine, something entirely different may happen. The one thing you can predict for sure is that this pattern will annoy whoever has to read your code.

在编译器和机器的某些其他组合中,可能会发生完全不同的情况。可以肯定的是,这种模式会惹恼任何需要阅读代码的人。

Try this and let me know.

试试这个,让我知道。

#2


8  

How to modify value of const variable?

如何修改const变量的值?

No! You shouldn't modify a const variable.
The whole point of having a const variable is to be not able to modify it. If you want a variable which you should be able to modify, simply don't add a const qualifier on it.

不!不应该修改const变量。拥有一个const变量的关键是不能修改它。如果您想要一个您应该能够修改的变量,请不要在其上添加const限定符。

Any code which modify's a const forcibly through (pointer)hackery invokes Undefined Behavior.

任何修改(指针)的代码都会调用未定义的行为。

An Undefined Behavior means that the code is non conforming to the standard specifications laid out by the C standard and hence not a valid code. Such a code can show any behavior and it is allowed to do so.

未定义的行为意味着代码不符合C标准规定的标准规范,因此不是有效的代码。这样的代码可以显示任何行为,并且允许这样做。

#3


6  

By defining i as const, you promised not to modify it. The compiler can rely on that promise and assume that it's not modified. When you print the value of i, the compiler can just print 10 rather than loading whatever value is currently stored in i.

通过将i定义为const,您承诺不修改它。编译器可以依赖这个承诺并假设它没有被修改。当您打印i的值时,编译器可以只打印10,而不加载当前存储在i中的任何值。

Or it can choose to load the value. Or it can cause your program to crash when you try to modify i. The behavior is undefined.

或者它可以选择加载该值。或者当你试图修改i时,它会导致你的程序崩溃。

You'll likely see different behavior with gcc depending on the optimization options (-O1, -O3).

根据优化选项(-O1, -O3),您可能会看到gcc的不同行为。

Oh, and void main() is incorrect; it should be int main(void). If your textbook tells you to use void main(), you should get a better book.

噢,void main()是不正确的;它应该是int main(void)。如果您的教科书告诉您使用void main(),您应该得到一本更好的书。

#4


2  

Take a look at Can we change the value of an object defined with const through pointers?

我们可以通过指针来改变一个对象的值吗?

Long story short, it's an undefined behaviour. It can result dependently on compiler/machine.

长话短说,这是一种没有定义的行为。它的结果依赖于编译器/机器。

#5


0  

You can not modify the value of const variable if you compile this code in gcc it will show

如果您在它将显示的gcc中编译此代码,则不能修改const变量的值

error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]

and show undefined behave

并显示未定义的行为

The maiin thing is that we can only modify the variable when we can access the address without address we can't do anything. That's the same thing with Register storage class.

maiin的意思是我们只能修改变量当我们可以访问没有地址的地址时我们什么都做不了。寄存器存储类也是这样。

#1


12  

Yes, you can do it with a little hack.

是的,你可以用一点技巧。

#include <stdio.h>
int main(){
    const int a = 0;
    *(int *)&a = 39;
    printf("%d", a);
}

In the above code, a is a const int. With the little hack, you can change the constant value.

在上面的代码中,a是一个const int.通过这个小技巧,您可以更改常量值。

Update: Explanation

更新:解释

In the above code, a is defined as a const. For example a has a memory addr 0x01 and therefore &a returns the same. When it is casted with (int *) it becomes another variable referred as a pointer to the const. When it is accessed with * again, the another variable can be accessed without violation of the const policy because it is not the original variable, but the changes are reflected because it is referred as address to the pointer.

在上面的代码中,a被定义为const。例如,a有一个内存addr 0x01,因此&a也返回相同的结果。当它被(int *)赋值时,它就变成了另一个变量,称为指向const的指针。当它再次被*访问时,可以不违反const策略地访问另一个变量,因为它不是原始的变量,而是因为它被称为指针的地址而反映了这些变化。

This will work on older versions like Borland C++ or Turbo C++, however no one is using it now a days.

这将适用于较老的版本,如Borland c++或Turbo c++,但是现在已经没有人使用它了。

It's "undefined behaviour", 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 const 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!)

在这种情况下,最常见的情况是,答案将是“是”。变量const或not只是内存中的一个位置,您可以打破const的规则,简单地覆盖它。(当然,如果程序的其他部分依赖于常量的const数据,这将导致严重的错误!)

However in some cases -- most typically for const static data -- 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静态数据——编译器可能会将这些变量放在内存的只读区域中。例如,MSVC通常将静态ints放在可执行文件的.text段中,这意味着如果您试图写入操作系统将抛出保护错误,程序将崩溃。

In some other combination of compiler and machine, something entirely different may happen. The one thing you can predict for sure is that this pattern will annoy whoever has to read your code.

在编译器和机器的某些其他组合中,可能会发生完全不同的情况。可以肯定的是,这种模式会惹恼任何需要阅读代码的人。

Try this and let me know.

试试这个,让我知道。

#2


8  

How to modify value of const variable?

如何修改const变量的值?

No! You shouldn't modify a const variable.
The whole point of having a const variable is to be not able to modify it. If you want a variable which you should be able to modify, simply don't add a const qualifier on it.

不!不应该修改const变量。拥有一个const变量的关键是不能修改它。如果您想要一个您应该能够修改的变量,请不要在其上添加const限定符。

Any code which modify's a const forcibly through (pointer)hackery invokes Undefined Behavior.

任何修改(指针)的代码都会调用未定义的行为。

An Undefined Behavior means that the code is non conforming to the standard specifications laid out by the C standard and hence not a valid code. Such a code can show any behavior and it is allowed to do so.

未定义的行为意味着代码不符合C标准规定的标准规范,因此不是有效的代码。这样的代码可以显示任何行为,并且允许这样做。

#3


6  

By defining i as const, you promised not to modify it. The compiler can rely on that promise and assume that it's not modified. When you print the value of i, the compiler can just print 10 rather than loading whatever value is currently stored in i.

通过将i定义为const,您承诺不修改它。编译器可以依赖这个承诺并假设它没有被修改。当您打印i的值时,编译器可以只打印10,而不加载当前存储在i中的任何值。

Or it can choose to load the value. Or it can cause your program to crash when you try to modify i. The behavior is undefined.

或者它可以选择加载该值。或者当你试图修改i时,它会导致你的程序崩溃。

You'll likely see different behavior with gcc depending on the optimization options (-O1, -O3).

根据优化选项(-O1, -O3),您可能会看到gcc的不同行为。

Oh, and void main() is incorrect; it should be int main(void). If your textbook tells you to use void main(), you should get a better book.

噢,void main()是不正确的;它应该是int main(void)。如果您的教科书告诉您使用void main(),您应该得到一本更好的书。

#4


2  

Take a look at Can we change the value of an object defined with const through pointers?

我们可以通过指针来改变一个对象的值吗?

Long story short, it's an undefined behaviour. It can result dependently on compiler/machine.

长话短说,这是一种没有定义的行为。它的结果依赖于编译器/机器。

#5


0  

You can not modify the value of const variable if you compile this code in gcc it will show

如果您在它将显示的gcc中编译此代码,则不能修改const变量的值

error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]

and show undefined behave

并显示未定义的行为

The maiin thing is that we can only modify the variable when we can access the address without address we can't do anything. That's the same thing with Register storage class.

maiin的意思是我们只能修改变量当我们可以访问没有地址的地址时我们什么都做不了。寄存器存储类也是这样。