Quantcast
Channel: Intel® Software - Intel® C++ Compiler
Viewing all articles
Browse latest Browse all 2797

Intel C++ Compiler 16.0.3 fails to compile valid code if copy constructor is deleted

$
0
0

The Intel C++ Compiler version 16.0.3 fails to compile the following code (The same code compiles fine with ICC 16.0.2):

class TestClass {
public:
  // default constructor, destructor, move constructor, move assignment operator
  TestClass() noexcept = default;
  ~TestClass() noexcept = default;
  TestClass(TestClass&&) noexcept = default;
  TestClass& operator=(TestClass&&) noexcept = default;

  // delete copy constructor and copy assignment operator
  TestClass(const TestClass&) noexcept = delete;
  TestClass& operator=(const TestClass&) noexcept = delete;

  TestClass Copy() const noexcept;

private:
  int fTestMember;
};

TestClass TestClass::Copy() const noexcept {

  TestClass copy;
  copy.fTestMember = fTestMember;
  // This should be possible by return value optimization - neither copy
  // constructor nor move constructor should be called!
  return copy;
}

int main(int argc, char** argv) {

  TestClass a;
  TestClass b = a.Copy();
  return 0;
}

This is on Linux with GCC 6.1.1 backend, but I have reproduced the same problem with GCC 4.9.3 and GCC 5.3.0. The compiler is invoked as follows:

icpc -std=c++11 -o test test.cc

The error message is:

test.cc(28): error: function "TestClass::TestClass(const TestClass &)" (declared at line 13) cannot be referenced -- it is a deleted function
   return copy;
          ^

compilation aborted for test.cc (code 2)

If I explicitly declare the move constructor myself like this:

--- test.cc     2016-05-05 17:15:10.314216763 +0200
+++ test.cc.new 2016-05-05 17:19:32.069354954 +0200
@@ -1,9 +1,12 @@
+#include <algorithm>
+#include <iostream>
+
 class TestClass {
 public:
   // default constructor, destructor, move constructor, move assignment operator
   TestClass() noexcept = default;
   ~TestClass() noexcept = default;
-  TestClass(TestClass&&) noexcept = default;
+  TestClass(TestClass&&) noexcept;
   TestClass& operator=(TestClass&&) noexcept = default;

   // delete copy constructor and copy assignment operator
@@ -16,6 +19,12 @@
   int fTestMember;
 };

+TestClass::TestClass(TestClass&& other) noexcept
+  : fTestMember(std::move(other.fTestMember)) {
+
+  std::cout << "Move constructor."<< std::endl;
+}
+
 TestClass TestClass::Copy() const noexcept {

   TestClass copy;

Then the code compiles. But when the code is then execute, I don't get a "Move constructor." message on stdout so the move constructor was not called.


Viewing all articles
Browse latest Browse all 2797

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>