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

标签 c++ c compiler-construction constants

<分区>

#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;
}

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

//In C:
4
6

//In C++:
4
4

最佳答案

尝试修改 const 值(只读值)是未定义行为。输出可以是任何东西,或者程序可能会崩溃,或者将你的狗插入太空。您已收到警告。

关于const,常量和只读值

const 是一个错误的关键字,因为它并不意味着“常量”,而是“只读”。 “常量”是赋予只读 的名称,仅此而已。 “只读”(此处)的反义词是“读写”,“常量”的反义词是“可变”。可变是 C 和 C++ 中的默认值(除了一些罕见的特殊情况,如 lambda)。考虑:

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;

你什么时候可以这样做?

唯一允许您强制转换 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);
}

怎样做才能不被咬?

  • 确保您自己的代码的常量正确性。如果函数采用指向它不会修改的值的指针,请将其设为只读。
  • 考虑您的 Actor 阵容。很少需要转换,也不能过度使用:它们基本上告诉编译器“闭嘴,我明白了”。如果您真的不这样做,那么您的编译器将无济于事。
  • 思考你的 const 转换。 两次。它们极少有用,如果处理不当则极易爆炸。

关于c++ - C 和 C++ 中 const 变量的不同输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25425941/

相关文章:

c - 将指针元素赋值给数组中的另一个指针元素是什么意思?

c - 如何打破 C 中的递归?

Eclipse 编译器选项 - 如何设置调试级别

python - 如何运行需要一组模块的在线 python 代码?

c++ - MinGW/CMake 对 ZLib 的 undefined reference

c++ - 将 boost::lexical_cast 与 std::transform 一起使用

c - Realloc 在循环内第 10 次迭代后失败

c++ - 在 "assert"(C++) 中使用 switch 语句

c++ - C++ Small String Optimized (SSO) 如何与容器一起工作?

.net - .NET 中类加载器的等效项