【问题标题】:Why is an implicit conversion from non-const to const allowed for pointers in the first place?为什么首先允许指针从非常量到常量的隐式转换?
【发布时间】:2016-08-24 13:32:22
【问题描述】:

我了解在处理值时从 non-constconst 的隐式转换并不危险,例如:

int mutable = 5;
const int immutable = mutable;

但是,在使用指针时,我可以执行以下操作:

int some_number = 5;
int *mutable = &some_number;
const int *immutable = mutable;    // <= Legal, but isn't it dangerous?

// Let's try to break const
printf("%d\n", *immutable);        // Prints 5
mutable[0] = 10;
printf("%d\n", *immutable);        // Prints 10

顺便说一句,对于双指针,这是不允许的(至少你会得到一个警告)!请参阅this 问题和其中的参考资料。

【问题讨论】:

  • 常量指针的常见用例是作为函数参数。这告诉函数的用户(以及编译器)该函数不会改变指针指向的数据。
  • 您的示例没有“破坏 const”,因为被修改的对象 (some_number) 不是 const。在指针目标上使用 const 并不意味着“如果你读了两次就保证产生相同的值,中间还会发生一些其他的事情”
  • const 视为承诺。为什么有人要违背自己的诺言?
  • 您的代码中没有const 限定指针!
  • @Olaf:这不是重点,而是基础价值的变化

标签: c pointers const-correctness


【解决方案1】:

来自the C11 standard (draft N1570)

6.7.3 类型限定符

语法

  1. 类型限定符:
    const
    restrict
    volatile
    _Atomic

[...]

语义:

  1. 与限定类型关联的属性仅对左值表达式有意义。

[...]

示例 1

声明的对象

extern const volatile int real_time_clock;

可由硬件修改,但不能分配、递增或递减。

简单来说:

const 并不意味着值永远不会改变。这只意味着不允许改变它1.

对于被调用者const 是一个限制,而不是一个承诺。
然而,对于调用者,它一个承诺。将const 指针传递给函数,您可以放心地假设该函数不会更改您的数据2,因此是“向您做出承诺”。


1 ...通过带有const限定符的标识符。
2 ...通过传递给它的const参数。

【讨论】:

  • 我忘了说我用的是C99,但我猜那里的标准是相似的。感谢您的澄清!
  • 但奇怪的是,对于双指针,确实会发出警告,以防止我刚才对单指针所做的事情,请参阅c-faq.com/ansi/constmismatch.html
  • "只表示不允许你修改。" - 甚至没有!我的意思是程序员保证不会修改它。
  • 将 const 指针传递给函数,您可以放心地假设该函数不会更改您的数据,因此是“向您做出承诺” 这是不正确的,该函数仍可能通过全局值的其他参数更改数据。
  • 这不是答案中写的。您的评论补充说:通过该论点,这是一个重要的区别。
猜你喜欢
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-02
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多