0

In g++ , element access operator for const std::vector<> is defined as follows: (/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); } 

But the following code compiles with no problem using 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;} 

So I'm changing the contents of the vector passed by const reference.

According to cppreference.com , operator[] is overloaded:

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

In which case compiler will take the second overload?

4
  • 3
    1. You can do many dangerous things with casts, 2. It's not a problem per se to modify something that was passed by const reference. It would only be a problem if you actually passed a const object to this function. Commented Jul 6, 2017 at 23:25
  • Also your code would be UB if passed an empty vector Commented Jul 6, 2017 at 23:26
  • 2
    classic c cast is a sledgehammer - it will do whatever you say. see what happens with static_cast Commented Jul 6, 2017 at 23:38
  • Basically all of these answers take a long way of saying that a C-style cast will perform the function of a const_cast (among other things). Commented Jul 6, 2017 at 23:44

1 Answer 1

1

On a range from "screwriver" to "table saw", the C-style cast is a mortar strike.

When the C-style cast expression is encountered, the compiler attempts to interpret it as the following cast expressions, in this order:
a) const_cast<new_type>(expression);
b) static_cast<new_type>(expression), with extensions [...];
c) static_cast (with extensions) followed by const_cast;
d) reinterpret_cast<new_type>(expression);
e) reinterpret_cast followed by const_cast.

It will literally pile up increasingly dangerous casts until the type system bends and/or something breaks. You should use it only when you definitely, absolutely, need to disable every safety you can to perform an operation that goes outside of the normal rules of the language.

In that case, you must know exactly what you're doing, and making a mistake will pretty much always trigger UB without diagnostic (because you just told the compiler to shut up and trust you).

Forcefully modifying an unknown const object is not a good idea -- unless you can prove it has originally been declared as non-const, you're off to UB-land.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.