C++ const 正确性漏洞或意外使用?

Posted

技术标签:

【中文标题】C++ const 正确性漏洞或意外使用?【英文标题】:C++ const correctness vulerability or unintended usage? 【发布时间】:2013-06-09 05:22:34 【问题描述】:

我遗漏了一些东西,或者 const-correctness 与指针(或者可能是智能指针,因为这是我测试过的?)的预期效果不太一样。无论如何,这是我在尝试 PIMPL 习语的变体时观察到的。

我声明了以下内容:

class A 
public:
  A(...);
  ...
  bool update_stuff(...) const;
  ...
protected:
  bool update_stuff_impl(...) const;
  ...
private:
  struct pimpl;
  pimpl* m_pimpl;
;

对于实施,我有类似的东西:

struct A::pimpl 
  pimpl(...): some_data(new some_type());
  ...
  some_method1(...); // Modifies content of some_data
  some_method2(...); // Modifies content of some_data 
  ...

  boost::shared_ptr<some_type> some_data;
;

A::A(...): m_pimpl(new pimpl(...)) 
  ...


bool A::update_stuff(...) const 
   if( !update_stuff_impl(...) ) 
      return false;
   
   return true;


bool A::update_stuff_impl(...) const 
   //-Change content of pimpl::some_data here
   m_pimpl->some_method1(...);
   m_pimpl->some_method2(...);
   return true;

我无法理解的是,当我实际修改 A::pimpl::some_data 时,我如何能够摆脱对函数 A::update_stuff(...)A::update_stuff_impl(...) 使用 const 限定符??!或者这是预期的行为还是只是简单的错误使用?如果是后者之一,如果您能确定如何纠正它,请不胜感激?

感谢您的时间和兴趣。

【问题讨论】:

由于您没有更改任何类成员,因此 const 正确性仍然存在,例如在 update_stuff_impl 中,您不会将指针 m_pimpl 更改为指向其他内容! 好的..就这样?我也是这么想的,但出于某种原因,我认为 const-correctness 检查的不止这些。我想它只检查指针而不是它的内容是有道理的,因为这可能是另一个指针,它可能指向另一个指针......等等,这将是太多的强制执行。嗯,这清除了它。如果你喜欢,你可以把它写成答案,我会选择它。谢谢。 You underestimate compilers. 【参考方案1】:

这不是一个新发现,您可以阅读 C++ 中的“const is shallow”之类的内容。是什么导致了物理和 逻辑 const 之间的自然区别(也请在第二个之后阅读)。

如果您在课堂上有指针,无论是聪明的还是愚蠢的,您都可能涉及到这个问题并且必须仔细设计。考虑到修改指针另一端的附加数据没有被发现。

可能的解决方法是使指针变为 const T* 并添加返回 T* 的私有成员函数。另一个是一般限制对指针的直接访问,并且需要一对函数,一个是常量,另一个是非常量。

【讨论】:

【参考方案2】:

C++ 保护pimpl* m_pimpl 变量的常量。它不允许更改指针的值。但它允许对这个指针指向的对象做任何事情。一般没有办法保护它。

例如,考虑一个类成员变量int a; int* b;。在类成员函数中,我们可以执行以下操作:

int a_copy = a;
a_copy = 42;
int* b_copy = b;
*b_copy = 42;

这里的a_copyb_copy 是局部变量。它们不受您所在对象的 const 保护。因此可以使用 const 方法执行此代码。不同的是这里a变量值没有改变,*b值改变了。由于可以轻松复制指针,因此编译器无法知道某个指针是否等于位于 const 对象的成员值中的任何指针。

【讨论】:

以上是关于C++ const 正确性漏洞或意外使用?的主要内容,如果未能解决你的问题,请参考以下文章

防止 C++ 中的意外对象复制

UglifyJS 抛出意外的标记:keyword (const) with node_modules

意外的输出为零

巧合?严重RCE漏洞竟被意外修复

const使用

const 和 constexpr