C和C++中const变量的不同输出

Nid*_* MS 1 c c++ compiler-construction const

#include <stdio.h>

int main(void) {
    const int a = 4;

    int *p = (int*)&a;
    printf("%d\n", a);

    *p = 6;
    printf("%d\n", a);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

代码在C和C++编译器上提供不同的输出:

//In C:
4
6

//In C++:
4
4
Run Code Online (Sandbox Code Playgroud)

Que*_*tin 5

尝试修改const值(只读值)是未定义行为.输出可以是任何东西,或程序可能崩溃,或推动你的狗进入太空.你被警告过了.

关于const,常量和只读值

const是一个选择不当的关键字,因为它不代表"常量",而是"只读"."常量"是给予只读的名称,没有别的.与"只读"(此处)相反的是"读写",与"常量"相反的是"可变".Mutable是C和C++中的默认值(除了一些罕见的极端情况,如lambdas).考虑:

int i = 4;       // (mutable) Value
int const j = 4; // Read-only value, a.k.a constant

// Pointer to a (mutable) value. You can write to the value through it.
int *pi = &i;

// Pointer giving read-only access to a value. The value
// is still mutable, but you can't modify it through cpi.
int const *cpi = &i;

// Since the value is mutable, you can do that and write to *p2i
// without trouble (it's still bad style).
int *p2i = (int*)cpi;

// Pointer giving read-only access to a value.
// The value is a constant, but you don't care
// since you can't modify it through cpj anyway.
int const *cpj = &j;

// This is legal so far, but modify *pj
// (i.e the constant j) and you're in trouble.
int *pj = (int*)cpj;
Run Code Online (Sandbox Code Playgroud)

你什么时候能做到这一点?

允许抛弃的唯一情况const是将指针(或引用)传递给您无法修改的错误声明的函数(或类似函数):

// Takes a non-const pointer by error,
// but never modifies the pointee for sure
int doSomething(Foo *foo);

// Your function, declared the right way
// as not modifying the pointee
int callDoSomething(Foo const *foo) {
    // Work around the declaration error.
    // If doSomething ever actually modifies its parameter,
    // that's undefined behaviour for you.
    int bar = doSomething((Foo*)foo);
}
Run Code Online (Sandbox Code Playgroud)

你有什么不被咬的?

  • 确保您自己的代码中的const正确性.如果函数接受指向它不会修改的值的指针,则将其设置为只读.
  • 思考你的演员.转换很少是必要的,不能过度使用:它们基本上告诉编译器"闭嘴,我得到了".如果你真的没有,那么,你的编译器将无济于事.
  • 思考你的const演员.两次.它们极少有用,如果处理不当则极具爆炸性.

  • @ user3791372注意:`const`并不完全意味着"常量",而是"只读".只有`const` _values_才是真正的常量(并且在改变时触发UB). (2认同)
  • 你总是被允许抛弃const.不允许的是尝试修改const对象. (2认同)