改变C中的const值

Man*_*nas 14 c c++

我在下面的代码片段中找到了

const int i = 2;  
const int* ptr1= &i;  
int* ptr2 = (int*)ptr1;  
*ptr2 =3;
Run Code Online (Sandbox Code Playgroud)

i价值变为3.我想知道的是为什么允许这样做.有什么情况可以变得有用?

Gra*_*and 30

这是允许的,因为你通过将它转换为非const指针来推翻ptr1的constness.这就是演员阵容非常危险的原因.

请注意,某些编译器(如GCC)不允许您像这样抛弃const状态.

  • 您应该注意,当您丢弃constness并尝试覆盖数据时,您会得到未定义的行为. (11认同)
  • @Manas:没有.有些架构甚至没有只读内存.第6.7.3/2节的脚注114说:"实现可能会在只读存储区域中放置一个非易失性的const对象.此外,如果从未使用过地址,则实现不需要为这样的对象分配存储空间". (3认同)

dmc*_*kee 12

你通过玩指针技巧打破了恒定性保证.这不能保证一直工作,并且几乎可以调用任何行为,具体取决于您抛出它的系统/ OS /编译器.

不要那样做.

或者至少不要这样做,除非你真的知道自己在做什么,甚至理解它并不是最便携的.


Ste*_*sop 10

"允许"是"被阻止"的反对,但它也与"被禁止"相反.您已经看到,不会阻止修改您的const对象,但这并不意味着它是允许的.

在"允许"的意义上,修改const对象不是"允许的".标准没有定义程序的行为(见6.7.3/5).恰好在您的实现上,在该运行中,您看到了值3.在另一个实现或另一天,您可能会看到不同的结果.

但是,它并没有被"阻止",因为在C转换工作的方式下,在编译时检测它是一个停滞的问题.在运行时检测它需要在所有内存访问中进行额外检查.该标准旨在不对实现施加大量开销.

抛弃const的原因是支持的,因为如果你有一个指向非const对象的const指针,那么该语言允许你(在两种意义上)修改该对象.为此,您需要摆脱const限定符.这样做的结果是程序员也可以从指向实际为const的对象的指针中丢弃const限定符.

这是一个(稍微愚蠢的)代码示例,它抛弃了const限定符,原因如下:

typedef struct {
    const char *stringdata;
    int refcount;
} atom;

// returns const, because clients aren't allowed to directly modify atoms,
// just read them
const atom *getAtom(const char *s) {
    atom *a = lookup_in_global_collection_of_atoms(s);
    if (a == 0) {
        // error-handling omitted
        atom *a = malloc(sizeof(atom));
        a->stringdata = strdup(s);
        a->refcount = 1;
        insert_in_global_collection_of_atoms(a);
    } else {
        a->refcount++;
    }
    return a;
}

// takes const, because that's what the client has
void derefAtom(const atom *a) {
    atom *tmp = (atom*)a;
    --(tmp->refcount);
    if (tmp->refcount == 0) {
        remove_from_global_collection_of_atoms(a);
        free(atom->stringdata);
        free(atom);
    }
}
void refAtom(const atom *a) {
    ++(((atom*) a)->refcount);
}
Run Code Online (Sandbox Code Playgroud)

这很愚蠢,因为更好的设计是前向声明atom,使指针完全不透明,并提供访问字符串数据的功能.但是C并不要求你封装所有内容,它允许你返回指向完全定义类型的指针,并且它希望支持这种const用法来呈现一个"真正"可修改的对象的只读视图.


pmg*_*pmg 5

const 真的意思是"只读".

正如您所知,const对象的价值可以改变,但您必须使用不正确的方法来做到这一点.在使用这些狡猾的方法时,您可以调用未定义的行为.