【问题标题】:c++ - Why a std::vector<>::const_reference can cast to a non-const pointer? [duplicate]c++ - 为什么 std::vector<>::const_reference 可以转换为非常量指针? [复制]
【发布时间】:2017-07-06 23:22:59
【问题描述】:

在 g++ 中,const std::vector 的元素访问运算符定义如下:(/usr/include/c++/7.1.1/bits/stl_vector.h)

/**
   *  @brief  Subscript access to the data contained in the %vector.
   *  @param __n The index of the element for which data should be
   *  accessed.
   *  @return  Read-only (constant) reference to data.
   *
   *  This operator allows for easy, array-style, data access.
   *  Note that data access with this operator is unchecked and
   *  out_of_range lookups are not defined. (For checked lookups
   *  see at().)
   */
  const_reference
  operator[](size_type __n) const _GLIBCXX_NOEXCEPT
  {
__glibcxx_requires_subscript(__n);
return *(this->_M_impl._M_start + __n);
  }

但是下面的代码使用g++ -c const-vector.cpp -Wall -pedantic编译没有问题

#include <vector>

void sum(const std::vector<int>& data){
  int *ptr;
  ptr = (int*) &data[0];
  if (data.size()>2) 
    for (unsigned int i=1;i<data.size();i++) 
      ptr[0]+=ptr[i];
return;}

所以我正在更改由 const 引用传递的 vector 的内容。

根据cppreference.comoperator[] 被重载:

reference       operator[]( size_type pos );
const_reference operator[]( size_type pos ) const;

在什么情况下编译器会进行第二次重载?

【问题讨论】:

  • 1.你可以用强制转换做很多危险的事情,2。修改通过 const 引用传递的东西本身不是问题。如果您实际上将 const 对象传递给此函数,这只会是一个问题。
  • 如果传递一个空向量,您的代码也将是 UB
  • classic c cast 是一把大锤——你说什么都会做。看看 static_cast 会发生什么
  • 基本上所有这些答案都需要很长一段时间才能说 C 风格的演员表将执行 const_cast 的功能(除其他外)。

标签: c++ gcc vector reference constants


【解决方案1】:

在从“螺丝刀”到“台锯”的范围内,C-style cast 是迫击炮弹。

当遇到 C 风格的转换表达式时,编译器会尝试将其解释为以下转换表达式,顺序如下:
一)const_cast&lt;new_type&gt;(expression);
b) static_cast&lt;new_type&gt;(expression),带有扩展名 [...];
c)static_cast(带扩展名)后跟const_cast
d)reinterpret_cast&lt;new_type&gt;(expression);
e) reinterpret_cast 后跟 const_cast

它实际上会堆积越来越危险的强制转换,直到类型系统弯曲和/或某些东西损坏。仅当您确定、绝对需要禁用所有安全措施以执行超出语言正常规则的操作时,才应使用它。

在这种情况下,您必须确切地知道自己在做什么,并且犯错几乎总是会在没有诊断的情况下触发 UB(因为您只是告诉编译器闭嘴并信任您)。

强行修改一个未知的const 对象不是一个好主意——除非你能证明它最初被声明为非常量,否则你就去UB-land。

【讨论】:

    猜你喜欢
    • 2015-12-15
    • 2019-06-12
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2013-04-28
    • 2017-05-13
    相关资源
    最近更新 更多