C 和 C++ 的常量正确性有什么区别?

问题描述 投票:0回答:3

我理解 const 正确性的含义,我的问题不是关于 const 正确性是什么。所以我不期待对此的解释或 C++-FAQ 链接。

我的问题是:

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

如果能引用各自标准的内容来明确差异,那就太好了。

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

我似乎不记得这些的原因(如果您能提供推理,特别感谢),但从我的脑海中,我可以记住:

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

我错过了什么?

c++ c constants language-design const-correctness
3个回答
34
投票

除了您引用的差异以及库的差异之外 史蒂夫·杰索普提到,

char* p1;
char const* const* p2 = &p1;

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

char* p1;
char const** p2 = &p1;

在标准采用前不久,有人意识到这 在 const 安全性上打了一个洞(因为

*p2
现在可以被分配一个
char const*
,这会导致
p1
被分配为
char const*
);和 没有实时深入分析问题,C委员会禁止任何 除顶级常量之外的其他
const
。 (即
&p1
可以是 分配给
char **
char **const
,但不分配给
char const**
也不是
char const* const*
。)C++ 委员会做了进一步的工作 分析,意识到问题仅在
const
时出现 水平之后是非
const
水平,并计算出必要的 措辞。 (参见标准中的§4.4/4。)


12
投票

在 C 中

const
声明不会产生常量表达式,即在 C 中,您不能在 case 标签中使用
const int
对象,作为位字段宽度或作为非 VLA 数组声明中的数组大小(所有这在 C++ 中是可能的)。此外,const 对象在 C 中默认具有外部链接(在 C++ 中为内部链接)。 C++语言的常量正确性规则支持以下标准转换

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

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

这些在 c 中不起作用。


7
投票

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

在 C 语言中我们可能有

 #define MAX_FOOS 10
 int foos[MAX_FOOS];

在 C++ 中,我们更希望能够编写

 const int max_foos = 10;
 int foos[max_foos];

要使其发挥作用,

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

当 C 委员会从 C++ 中采用 const 时,他们并没有采用对宏的反感,因此他们不需要这些语义。

© www.soinside.com 2019 - 2024. All rights reserved.