【问题标题】:Assigning pointers to pointers with or without qualifiers [duplicate]将指针分配给带有或不带有限定符的指针[重复]
【发布时间】:2013-09-09 09:07:42
【问题描述】:

编译时:

char* p2c;
const char* p2cc = p2c; //fine

因为 lhs 指向类型具有 rhs 指向类型的所有限定符,所以没有:

char** p2p2c;
const char** p2p2cc = p2p2c; //fail

但确实如此:

const char * const * p2cp2cc = p2p2c; //fine

为什么会发生这种情况?

【问题讨论】:

  • 最后一个例子只能用C++编译,不能用C编译。
  • 在 C 和 C++ 中就是这样。这是两种不同的语言,具有不同的 const 正确性规则。在 C++ 中,T ** 可转换为 const T* const *。在 C 中,T ** 可转换为 T* const *,但不能转换为 T* const *stackoverflow.com/a/5249001/187690
  • @AndreyT 您的示例以相反的含义列出了相同类型;d (T* const *)
  • 哦...复制粘贴错误。我的意思是说“在 C 中,T ** 可转换为 T* const *,但不能转换为 const T* const *
  • 我将引用您的部分答案,我觉得它特别简洁:C++ 说您可以在任何间接深度添加 const-qualification,只要您还添加 const-qualification一直到顶层。在 C 中,您只能将 const 限定添加到顶级指针指向的类型,但不能更深。

标签: c++ c pointers c99


【解决方案1】:

这不起作用:

char** p2p2c;
const char** p2p2cc = p2p2c; //fail

如果允许,您将被允许打破 const 正确性:

const int k = 10;
int *p;
int **pp = &p;
int const **kpp = pp;     // Should this be allowed, if so:
*kpp = &k;                // fine, kpp promises not to change it
                          // yet this does p = &k;
                          // p made no such promise! this is a hidden const_cast!
*p = 5;

如果允许赋值,您可以设置一个非 const 指针(中间)来引用一个常量值,这可能会以一种不明显的方式导致未定义的行为。通过禁止该操作,类型系统更安全。

但确实如此:

const char * const * p2cp2cc = p2p2c; //fine

这很好,因为中间指针是固定的,所以不可能重置中间指针来引用一个 const 对象并破坏 const-correctness

【讨论】:

  • 为什么可以安全地将char** 转换为char const * const *
  • @elmes: 因为中间指针也是const 意味着你不能将它重置为错误对象。
  • 现在看起来很合理,谢谢。
  • 同样,从 char**char const * const * 的隐式转换仅在 C++ 中可用,在 C 中不可用。
  • @AndreyT:我不知道,甚至没有阅读标签(我的错,因为我只过滤 C++,我倾向于忽略标签,尽管我不应该)
【解决方案2】:

cdecl 在这种情况下真的很有帮助。

const char** p2p2cc = declare p2p2cc as pointer to pointer to const char

const char * const * p2cp2cc = declare p2cp2cc as pointer to const pointer to const char

如您所见,第二个版本具有内部和外部指针 const,这意味着它也不能修改。第一个版本有内部指针 const 和外部非 const 从而打破了 constnes。

另一方面,这是可行的:

char** const p = p2p2c;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多