gpt4 book ai didi

c++ - 指针类型之间的转换规则,其中 cv 限定符是唯一的区别

转载 作者:行者123 更新时间:2023-11-30 04:16:54 24 4
gpt4 key购买 nike

这个问题具体与 C++98 相关,但如果您愿意,可以随意提供任何关于更新标准的有用信息。

如果您知道答案并想跳过其余部分,简短而有趣的是:

int **w;
int volatile* *x = w; // error
int volatile*const*y = w; // OK
int const *const*z = w; // OK

为什么 y 声明中 volatile 的右边必须有 const?如果允许对 x 的声明,有人可能会做出什么坏事?

在标准的 4.4.4 部分,它说:

A conversion can add cv-qualifiers at levels other than the first in multi-level pointers, subject to the following rules:

Two pointer types T1 & T2 are similar if there exists a type T and integer n > 0 such that:

  • T1 is CV10 ptr to CV11 ptr to ... CV1N T
  • T2 is CV20 ptr to CV21 ptr to ... CV2N T

... where each CVij is const, volatile, const volatile, or nothing. The n-tuple of cv-qualifiers after the first in a pointer type, e.g., CV11, CV12, ..., CV1N in the pointer type T1, is called the cv-qualification signature of the pointer type. An expression of type T1 can be converted to type T2 iff the following conditions are satisfied:

  1. the pointer types are similar
  2. for every j > 0, if const is in CV1j, then const is in CV2j, and similarly for volatile.
  3. if the CV1j and CV2j are different, then const is in every CV2k for 0 < k < j

... 之后它继续给出一个将 ** 分配给 const** 的示例。上面的强调是我的,斜体来自文档。

将其放入代码中:

 int CV13* CV12* CV11* CV10 b1;
int CV23* CV22* CV21* CV20 b2 = b1;

我对一些细节有点模糊......所以这里有一些问题或可能有缺陷的观察:

1) 它说在第一个以外的级别;这没有进一步详细说明,但是 CV20 可以是任何有效的 CV 限定符。

2) 底部的第三条规则说明如果 T2 在级别 j 添加 constvolatile,则级别 1 ... j-1 必须是 const(或遭受愤怒)。在下文中,星星的数量与顶部的不同,以强调第三条规则所说的内容:

int *****w;
int **volatile* * *x = w; // error
int **volatile*const*const*y = w; // OK
int **const *const*const*z = w; // OK

我明白为什么 z 需要它,但为什么 y 需要它? 4.4.4 中的示例大致如下所示,针对 volatile 情况进行了修改:

void f( int **x ) {
int volatile**y = x; // not allowed
// do some evil here
}

能放什么邪?

最佳答案

(注意:“这个问题特别与 C++98 相关”,但在标准的所有版本中,无论是过去还是现在(我敢打赌 future 也是如此),情况都是一样的,因为它本质上是关于 const-正确性并防止编码人员在类型系统中打开漏洞。)

由于标准使用通用术语“cv-qualifiers”,我发现仅使用“const”进行推理时更容易理解(没有“volatile ") [但请参阅下面的 volatile 示例]。 “C++ FAQ Lite”有一个相关条目:Why am I getting an error converting a Foo**Foo const**?

本质上,允许转换会让您静默修改const T(通过指向-const T 的指针):

int const theAnswer = 42;
int* p = 0; // int* p = &theAnswer; is not allowed of course...
int** pp = &p;
int const** ppc = pp; // <-- Error, but imagine this were allowed...
*ppc = &theAnswer; // &theAnswer is `int const*` and *ppc is `int const*` too,
// but it's also doing *pp = &theAnswer; i.e. p = &theAnswer;
*p = 999; // I.e. theAnswer = 999; => modifying a const int!

但是通过添加“第一级”const,转换 int const* const* pcpc = pp; 是有效的,因为编译器会阻止你做 *pcpc = &theAnswer; 之后(因为 *pcpcconst)。


编辑:至于 volatile,问题可能没有 const 明显,但允许转换会让您默默地错误访问(读或写)一个 volatile T 就好像它是 not volatile(通过指向 non-volatile T 的指针):

extern int volatile externTimer;
int* p = 0; // int* p = &externTimer; is not allowed...
int** pp = &p;
int volatile** ppv = pp; // <-- Error, but imagine this were allowed...
*ppv = &externTimer; // &externTimer is `int volatile*` and *ppv too,
// but it's also doing *pp = &externTimer; i.e. p = &externTimer;
int a1 = externTimer; // First read
int a2 = externTimer; // Second read, mandatory: the value may have changed externally
int b1 = *p; // First read
int b2 = *p; // Second read? may be optimized out! because *p is not volatile

但是通过添加“第一级”const,转换 int volatile* const* pcpv = pp; 是有效的,因为编译器会阻止你做 *pcpv = &externTimer; 之后(因为 *pcpvconst)。

关于c++ - 指针类型之间的转换规则,其中 cv 限定符是唯一的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17460149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com