francesco
francesco

Reputation: 7539

Implicit conversion to const of dynamically allocated arrays

In the following code, a class owns a dynamically-allocated array. It exposes a read-only access to this array via a public method that does an implicit conversion to const.

#include <array>

template <class T, std::size_t N>
class A {
  const unsigned int size;
  std::array<T, N> *s;
public:
  A(const unsigned int _size, const std::array<T, N>& def) :
     size(_size),
     s(new std::array<T, N>[size])
  {
    for (unsigned int i = 0; i < size; i++)
      s[i] = def;
  }
  ~A() { delete[] s; }

  std::array<T, N> const* const conf() const { return s; }
};

int main()
{
  A a(10, std::array<int, 3>{0, 0, 0});
  auto x = a.conf();
  return 0;
}

Does the implicit const conversion in A::conf() give rise to an overhead (for example by invoking a copy-constructor of the elements of A::s)?

Upvotes: 1

Views: 176

Answers (2)

BiagioF
BiagioF

Reputation: 9715

Does the implicit const conversion in A::conf() give rise to an overhead (for example by invoking a copy-constructor of the elements of A::s)?

No.

There is no "overhead", a pointer can be implicitly converted in its const-version. Generally, the conversion generates zero assembly instruction.


Additional Notes

Empirical Proof

A::conf() does not call any copy-constructor. From the generated assembly (gcc -O3):

A<int, 3ul>::conf() const:
        movq    %rdi, %rax
        ret

As you can see, it just returns the pointer without producing any further instructions.

Note: I disabled the "inlining optimization" here, otherwise the entire function would be optimized producing zero overhead.

Small Tips

  • Maybe a little bit off-topic, but it is good practice to avoid managing raw memory in modern C++ (whenever possible). What about using std::vector?

  • In the signature std::array<T, N> const* const conf() const the second const is always ignored by the compiler. You can omit making it more readable: std::array<T, N> const* conf() const.

Upvotes: 3

nivpeled
nivpeled

Reputation: 1838

conf() returns a pointer (std::array<T, N> const*). Thus auto x = a.conf(); deduces the type of x to be a const pointer std::array<T, N> const*. The address/pointer is copied by value (typically copy 4byte/8byte address depending on your system). No c'tor is called.

Upvotes: 0

Related Questions