C vs C++中的Const正确性

Alo*_*ave 59 c c++ const

我理解const正确性意味着什么,而我的问题不在于const正确性是什么.所以我不期待一个解释或C++ - FAQ链接.

我的问题是:

  • constC和constC++ 之间的语义差异是什么?
  • 差异的原因是什么?

从各自的标准中得出差异的报价将是很好的.

我经常在C和C++之间切换,我想知道在这样做时应该记住的重点.

我似乎不记得这些的原因(特别感谢你能提供一个推理)但是从我的头脑中,我记得:

  • C++中的const变量默认具有内部链接,而在C中它们具有默认的外部链接;
  • const对象可以在C++中用作编译时值,但不能在C中用作编译时值;
  • 字符串文字的指针必须是char const*C++中的,但在C中它可以是char*.

我错过了什么?

Jam*_*nze 26

除了您引用的差异,以及Steve Jessop提到的库差异,

char* p1;
char const* const* p2 = &p1;
Run Code Online (Sandbox Code Playgroud)

在C++中是合法的,但在C中不合法.从历史上看,这是因为C最初允许:

char* p1;
char const** p2 = &p1;
Run Code Online (Sandbox Code Playgroud)

在标准通过之前不久,有人意识到这在const安全方面打了一个洞(因为*p2现在可以分配一个 char const*,这导致p1被分配一个char const*); 没有实时深入分析问题,C委员会禁止除const顶级常量以外的任何其他内容.(即&p1可以被分配到一个char **或一个char **const,而不是一个char const** ,也不是char const* const*.)的C++委员会所做的进一步分析,认识到的问题是,只有当当前const 水平,随后通过非const水平,并制定了必要的措词.(参见标准中的§4.4/ 4.)

  • @StephenLin唯一的原因是那些仍然使用C的人过去常常陷入困境,并且往往忽略了`const`. (6认同)
  • @Norswap它们破坏了const-correctness,因为它们允许一个表达式修改一个const对象而没有显式的类型转换:`int const i = 42; int const*pi =&i; int*pi2; int const**ppi =&pi2; pii = pi;*pi2 = 0;`.最后一行打破了const-correctness.这个例子是在C标准化的最后发现的; 结果,C禁止所有隐含的顶级const添加.在标准化C++时,一个人做了更完整的分析,并且规则被自由化以允许添加顶级const,只要所有嵌套级别也是const. (4认同)

Pra*_*van 10

在C const声明中,不生成常量表达式,即在C中,不能const int在case标签中使用对象,在非VLA数组声明中使用位域宽度或数组大小(所有这些都可以在C++中使用).此外,const对象默认在C中具有外部链接(C++中的内部链接).C++语言的Const-correctness规则支持以下标准转换

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++
Run Code Online (Sandbox Code Playgroud)

这些在c中不起作用.


Ala*_*kes 5

其中一些差异的原因是允许我们摆脱预处理器宏,这是Bjarne的早期设计目标之一.

在C中我们可能有

 #define MAX_FOOS 10
 int foos[MAX_FOOS];
Run Code Online (Sandbox Code Playgroud)

在C++中,我们更愿意写

 const int max_foos = 10;
 int foos[max_foos];
Run Code Online (Sandbox Code Playgroud)

为此,max_foos需要在常量表达式中使用.它还需要具有内部链接,因此定义可以出现在标题中而不会导致多个定义错误,更重要的是使编译器更容易为其分配任何存储max_foos.

当C委员会从C++采用const时,他们没有采用对宏的反感,所以他们不需要这些语义.