当我想修改指向常量整数的指针时,为啥我的编译器不显示错误?
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);
因此,不允许尝试写入此位置(至少通过此指针),但您从中读取的值会定期且持续地更改。
[请注意,与上面的说法相反:这(可能)仍然存在——但对于受保护模式的操作系统,尝试在用户模式下直接访问它无疑会失败。]
【讨论】:
以上是关于当我想修改指向常量整数的指针时,为啥我的编译器不显示错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥字符串函数有一些参数作为 const char *(指向常量字符的指针)?