当我想修改指向常量整数的指针时,为啥我的编译器不显示错误?

Posted

技术标签:

【中文标题】当我想修改指向常量整数的指针时,为啥我的编译器不显示错误?【英文标题】:Why does not my compiler show an error when I want to modify a pointer to a constant integer?当我想修改指向常量整数的指针时,为什么我的编译器不显示错误? 【发布时间】:2017-02-19 04:03:15 【问题描述】:

这是代码。

    int main()
    int v=2;
    const int *p=&v;
    ++v; //Option 1: Does work, but why should it? 
    // ++*p; //Option 2: Does not work
                  

编译器按预期抛出选项 2 的错误。但它与选项 1 一起使用,当它修改指向常量整数的指针的内容时。为什么?或者,我对 const 的含义有什么误解吗?它仅适用于堆上的变量而不是堆栈上的变量吗?

【问题讨论】:

v 不是 const,为什么编译器不允许修改它? const 并不意味着“这个对象永远不能被修改”——它只是意味着“这个对象不能通过这个指针或引用被修改”。 @IgorTandetnik 永远不能修改 const 对象。您说的是指针上的非*** const 限定符(一个重要的区别 - const 在不同的上下文中表示不同的东西) @M.M 我确实在某种程度上简化了——也许太多了。尽管考虑 const 对象的一种方法是它不能被修改,因为你永远不能(合法地)获得非常量指针或对它的引用。 @IgorTandetnik 抛弃 const 是合法的。 (但是通过这样的指针写一个 const 对象是不合法的) 【参考方案1】:

或者,我对 const 的含义理解有误吗?

是的。

当你有:

int v = 2;
const int *p=&v;

您不能通过p 修改对象,但您仍然可以直接通过v 修改对象。您也可以通过另一个指针来修改对象。

int* p2 = &v
*p2 = 10; // OK.

【讨论】:

【参考方案2】:

const 并不真正意味着“恒定”,它基本上意味着“只读”。当您定义一个指向 const 对象的指针时,这并不意味着该对象永远不会改变——它只是意味着您不能通过该指针写入该对象

事实上,指定一个对象既是const(所以你不能改变它)又是volatile(表明其他东西可能会改变它)是完全允许的(有时是有意义的)。例如,在 MS-DOS 时代,Bios 在地址为40:6c(0x40 段中的偏移量 0x6c)处维护了一个计时器,它每 55 毫秒更新一次,但你不应该直接编写它,所以你可以定义一个指向它的指针:

long const volatile *bios_timer = MK_FP(0x40, 0x6c);

因此,不允许尝试写入此位置(至少通过此指针),但您从中读取的值会定期且持续地更改。

[请注意,与上面的说法相反:这(可能)仍然存在——但对于受保护模式的操作系统,尝试在用户模式下直接访问它无疑会失败。]

【讨论】:

以上是关于当我想修改指向常量整数的指针时,为啥我的编译器不显示错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥指针可以为NULL

为啥字符串函数有一些参数作为 const char *(指向常量字符的指针)?

定义了一个常数组,为啥能用指针改变数组元素的值?

C++中强行修改const常量的问题

为啥新的 Visual Studio 将字符串文字作为指向常量的指针?

C语言,用指针方式定义的字符串为啥不能修改?