C中的常量正确性

Posted

技术标签:

【中文标题】C中的常量正确性【英文标题】:Const-correctness in C 【发布时间】:2012-08-09 00:03:45 【问题描述】:

显然使用const 是一个好习惯,除非某些东西是可变的,但你能走多远?如果我有一个字符串数组,我的函数签名应该包括这个吗?

char const * const * const my_strings

我不会修改它无论如何,所以它是一个指向常量数组的第一个元素的常量指针,它指向常量字符数组的第一个元素。这很拗口,而且代码几乎不可读。这都是一个简单的数据结构,比如argv

我觉得 const 应该是默认的,应该有一个 mutable 关键字。

您通常只是那些consts 中的一个吗? 如果您仍然可以通过或多或少地取消引用来轻松更改它,那又有什么意义呢?

【问题讨论】:

关于您问题的后半部分,请参阅comp.lang.c FAQ 11.10 @JohnBartholomew:谢谢。我没有意识到我可以简单地投射以使消息消失。 是的,const 应该是默认的。我相信 Bjarne Stroustup 也说过同样的话,但他必须保持与 C 的向后兼容性。已经有一个关键字 mutable 【参考方案1】:

我通常会使用三个consts 中的两个:

const char *const *my_strings;

有时我会使用所有三个,但在我看来,最后一个是最不重要的。它仅有助于分析使用变量my_strings 的代码,而其他两个有助于分析具有指向my_strings 指向的数组或指向该数组元素的字符串的任何指针的代码。这通常是更多的代码,在几个不同的地方(例如函数的调用者和函数本身),因此是一项更难的任务。

使用变量本身的代码被限制在my_strings 的范围内,所以如果这是一个自动变量(包括函数参数),那么它是包含良好且更容易的任务。通过将其标记为const 所提供的帮助可能仍会受到赞赏,但它并不那么重要。

我还要说,如果char const * const * const my_strings“几乎不可读”,那么当你有更多的阅读 C 的练习时,情况就会改变,而且最好是练习而不是更改代码。编写新手可以轻松阅读的 C 代码有一些价值,但没有完成一些工作的价值 ;-)

您可以使用 typedef 来缩短变量定义,但代价是引入了会惹恼许多 C 程序员的间接:

typedef char const *ro_strptr;
ro_strptr const *my_strings;

无论出于何种原因,C 程序员通常希望在一个地方尽可能多地看到一种类型。只有当类型变得真正复杂(指向函数的类型)时,您才可以只使用 typedef 来缩写,而不必半信半疑地有人会抱怨它。

【讨论】:

几乎不可读,我并不是说它很难破译,因为它看起来像是很多线路噪音。 +1 使用 typedefs。值得注意的是,const-correctness 不能阻止任何人如果他们真的想要更改您的数据。因此,将 const 正确性完善到这种程度并不总是有帮助 - 它更多地表明预期用途。 @Scotty: const-correctness 可以防止其他 const-correct 代码更改我的数据。因此,如果他们真的想改变它,但有纪律,那么他们就会克制自己,系统就会起作用。没有自律的 C 程序员会导致很多未定义的行为,而修改 const 对象是他们这样做的众多方式之一 :-) 所以我同意它表示预期用途,实际上是 permitted 用途,但是我要指出的是,预期/允许的用途,即不同组件之间的书面合同,是工作程序和冒烟的废墟之间的全部。 我才意识到为什么三个const是不必要的:const char *const *const my_strings甚至const char *const my_string,在一个字符串的情况下,相当于把const放在@987654333等参数上@,无论如何都是按值传递的。当您说它仅有助于分析使用它的代码时,您暗示了这一点,但我发现这种方式更容易理解,因为我已经为自己决定 const 用于非指针类型在参数列表中是多余的。跨度>

以上是关于C中的常量正确性的主要内容,如果未能解决你的问题,请参考以下文章

为何c语言中出现“字符常量中的字符过多”错误

常量变量存储在 C 中的啥位置?

在不丢失 .data 常量的情况下混合汇编和 C 的正确标志是啥

下面定义Java的常量,正确的是()

c语言中的布尔类型、枚举类型是个啥概念?

C语言中的常量